


#include "../inc/dllemvb.h"



#ifdef PAYPASS_FUNC_SUPPORT

extern EMVBallocator gEmvballocator;

const unsigned char PaypassbReadrecordbadTag[50][2] = 
{
    //{0x9F,0x36},   //3M23-9200 case12
    {0x9f,0x69},
	{0,0}
};


const unsigned char PaypassbReadrecordformatbadTag[50][2] = 
{
    {0x9F,0x4C},
    {0xDF,0x4B},
    {0x9F,0x10},  //3G06-9310
    {0x9F,0x75}, 
    {0x9F,0x76}, 
    {0x9F,0x77}, 
    {0x9F,0x78},
    {0x9F,0x79},  // 3G06-9310-22
	{0,0}
};


const unsigned char PaypassbCCCbadTag[50][2] = 
{
    {0x9F,0x6E},
	{0x9F,0x70}, 
    {0x9F,0x71}, 
    {0x9F,0x72}, 
    {0x9F,0x73},
    {0x9F,0x74},  // 3G06-9310-22
	{0,0}
};


const unsigned char PaypassbGACbadTag[50][2] = 
{
    {0x9F,0x6B},
	{0x9F,0x4C},
	{0,0}
};

const unsigned char PaypassbFinselectA5badTag[50][2] = 
{
    {0x84,0x00},
	{0x82,0x00},
	{0,0}
};


const unsigned char PaypassbFinselectbf0cbadTag[50][2] = 
{
    {0x84,0x00},
	{0x82,0x00},
	{0x5F,0x2d},
	{0x81,0x00},
	{0,0}
};

const unsigned char PaypassbFinselectbadTag[50][2] = 
{
    {0x9f,0x4d},
	{0,0}
};


static const EMVTAG PaypssCDAmandatoryTag[] = 
{
	{TAG_CAPKI},
	{TAG_ICCPKCert},
	{TAG_ICCPKExp},
	{TAG_IPKCert},
	{TAG_IPKExp},
	{TAG_SDATagList},
	{"\x00\x00\x00\x00"}
};


static const EMVTAG PaypassIDSSpecTag[] =
{
    //{TAG_DRDOL},
    {TAG_DSODSCard},
    {TAG_DSID},
    {TAG_DSSlotAvail},
    {TAG_DSSlotManage},
    {TAG_DSSummary1},
    {TAG_DSUnpredictableNumber},
    {TAG_DSSummary2},
    {TAG_DSSummary3},
    {"\x00\x00\x00\x00"}

};


static const EMVTAG PaypssLISTSTag[] = 
{
	{TAG_PaypassDataNeeded},
	{TAG_TagsToRead},
	{TAG_PaypassDataToSend},
	{TAG_WriteBeforeGAC},
	{TAG_WriteAfterGAC},
	{"\x00\x00\x00\x00"}
};



unsigned char Paypassb_IDSCfgOpt_ActivatedStatus(void)
{

    unsigned char ret = 0;

    if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_DSVNTerm)&&dllemvb_avl_gettagitempointer((unsigned char *)TAG_DSOperatorID) != NULL)
    {
        ret = 1;
    }

    return ret;
}

unsigned char Paypassb_IfIDSTagCanKnown(unsigned char *tag, unsigned char taglen)
{

    unsigned char knownflag = 1;
    unsigned char tagindex;

    if(!Paypassb_IDSCfgOpt_ActivatedStatus())
    {

        tagindex = 0;
        while(memcmp(&PaypassIDSSpecTag[tagindex], "\x00\x00\x00\x00", 4) != 0 )
        {
            if(memcmp(tag, &PaypassIDSSpecTag[tagindex], taglen) == 0)
            {
                knownflag = 0;
                break;
            }
            tagindex++;
        }
    }

    return knownflag;

}
unsigned char paypassb_checktag_inlists(unsigned char *tag,unsigned char taglen)
{
	unsigned char i;

	for(i = 0;i < 20;i++)
	{
		if(gEmvballocator.EMVBallocator_memcmp(PaypssLISTSTag[i].Tag,"\x00\x00\x00\x00",4) == 0)
		{
			break;
		}
		
        if(gEmvballocator.EMVBallocator_memcmp(tag,&PaypssLISTSTag[i].Tag,taglen) == 0)
        {
        	return 1;
        }
		
	}
	
	return 0;
	
}

int Paypassb_CheckListTagExist(unsigned char *srctag,unsigned char srctaglen,unsigned char *dstlistdata,unsigned int dstlistdatalen,unsigned short *tagdatalen,unsigned char type)
{
    unsigned char taglen;
	unsigned short i,len,offset;
	
    for(i = 0;i < dstlistdatalen;)
    {
		offset = i;  //¿½±´Êý¾ÝµÄÆ«ÒÆ
		
        taglen = 0;
		if((dstlistdata[i]&0x1f) == 0x1f)
		{
			
			taglen++;
			if(dstlistdata[i+1]&0x80)
			{
				taglen++;
			}
			
		}
		taglen++;
		
		//tagdatalen
		i += taglen;
        
		len = 0;
		if(type != DEKTAGTYPE_TAG)
		{
			if(ParseExtLen(dstlistdata,&i,&len))
			{
				return -1;
			}
			
			if(type == DEKTAGTYPE_TAGANDLEN)  //tag+len Ã»ÓÐÊý¾Ý
			{
				len = 0;
			}
		}
		
		
		if(taglen == srctaglen)
		{
		    //Ô­À´ÁÐ±íÖÐÒÑ´æÔÚ¸Ã TAG
			if(gEmvballocator.EMVBallocator_memcmp(srctag,&dstlistdata[offset],taglen) == 0)
			{
				*tagdatalen = i-offset+len;
				return offset;
			}
			
		}

		i += len;
		
    }
	return -1;
}


int Paypassb_CheckTagInDOL(unsigned char *DOLtag,unsigned char *srctag)
{
    unsigned char taglen,srctaglen;
	unsigned short i;
    EMVTAGCVLITEM *item;

	srctaglen = 0;
	if((srctag[0]&0x1f) == 0x1f)
	{
		srctaglen++;
		if(srctag[1]&0x80)
		{
			srctaglen++;
		}
		
	}
	srctaglen++;
	
	item = dllemvb_avl_gettagitempointer(DOLtag);
	if(item != NULL)
	{
	    for(i = 0;i < item->len;)
	    {
	        taglen = 0;
			if((item->data[i]&0x1f) == 0x1f)
			{
				taglen++;
				if(item->data[i+1]&0x80)
				{
					taglen++;
				}
				
			}
			taglen++;
			
			if(taglen == srctaglen)
			{
			    //Ô­À´ÁÐ±íÖÐÒÑ´æÔÚ¸Ã TAG
				if(gEmvballocator.EMVBallocator_memcmp(srctag,&item->data[i],taglen) == 0)
				{
					return i;
				}
				
			}
	        
			i += taglen+1;
			
	    }
	}
    
	
	return -1;
}



//sx2017
unsigned int Paypassb_AddListToList_Process(unsigned char *srctagdata,unsigned int srctagdatalen,unsigned char *dsttagdata,unsigned int dsttagdatalen,unsigned char type)
{
	
    unsigned char taglen;
	unsigned short i,len,offset,updatedatalen,j;
    unsigned char *tempbuf;//[512];
    int dstoffset;

	tempbuf = (unsigned char *)emvblib_malloc(1024+128);
    for(i = 0;i < srctagdatalen;)
    {
    	
        offset = i;  //¿½±´Êý¾ÝµÄÆ«ÒÆ
		
        taglen = 0;
		if((srctagdata[i]&0x1f) == 0x1f)
		{
			
			taglen++;
			if(srctagdata[i+1]&0x80)
			{
				taglen++;
			}
			
		}
		taglen++;
		
		//tagdatalen
		i += taglen;
		len = 0;
		if(type != DEKTAGTYPE_TAG)
		{
			if(ParseExtLen(srctagdata,&i,&len))
			{
				return 0;
			}
			
			if(type == DEKTAGTYPE_TAGANDLEN)
			{
				len = 0;
			}
			
		}
		
		

		//¼ì²édst listÖÐÊÇ·ñÒÑ¾­´æÔÚ
		dstoffset = Paypassb_CheckListTagExist(&srctagdata[offset],taglen,dsttagdata,dsttagdatalen,&updatedatalen,type);
        #ifdef ZTPAYPASS_DEBUG
        emvb_printf("dstoffset = %d %d %d %d %d",dstoffset,i,offset,len,updatedatalen);
		#endif
		if(dstoffset >= 0) //tag ÒÑ¾­´æÔÚ
		{
			
		    if(i-offset+len == updatedatalen)
		    {
		    	//±È½ÏÊý¾ÝÊÇ·ñÒ»ÖÂ£¬²»Ò»ÖÂ²Å¸üÐÂ
		    	if(gEmvballocator.EMVBallocator_memcmp(&srctagdata[offset],&dsttagdata[dstoffset],updatedatalen))
		    	{
		    		gEmvballocator.EMVBallocator_memcpy(&dsttagdata[dstoffset],&srctagdata[offset],updatedatalen);
		    	}
				
		    }
			else   //¿Ï¶¨²»Ò»ÖÂ£¬ÐèÒª½øÐÐÊý¾Ý°áÒÆ
			{
			    #ifdef ZTPAYPASS_DEBUG
		        emvb_printf("copy data");
				#endif
				gEmvballocator.EMVBallocator_memcpy(tempbuf,dsttagdata,dstoffset); // dst offset 0,i 3,offset 0,len 0,updatedatalen 35
				j = offset;
                gEmvballocator.EMVBallocator_memcpy(&tempbuf[j],&srctagdata[offset],i-offset+len);
				j += i-offset+len;
				#ifdef ZTPAYPASS_DEBUG
		        emvb_printf("copy data1 dstoffset= %d %d %d",dstoffset,dstoffset+updatedatalen,dsttagdatalen-(dstoffset+updatedatalen));
				#endif
				gEmvballocator.EMVBallocator_memcpy(&tempbuf[j],&dsttagdata[dstoffset+updatedatalen],dsttagdatalen-(dstoffset+updatedatalen));
				j += dsttagdatalen-(dstoffset+updatedatalen);
				dsttagdatalen = j;
				#ifdef ZTPAYPASS_DEBUG
		        emvb_printf("copy data11 = %d",dsttagdatalen);
				#endif
				gEmvballocator.EMVBallocator_memcpy(dsttagdata,tempbuf,dsttagdatalen);
				#ifdef ZTPAYPASS_DEBUG
		        //API_TraceHex(DBG_APP_INFO,"copy data end",dsttagdata,dsttagdatalen);
				#endif
				
			}
			
		}
		else //tag ²»´æÔÚ,Ö±½Ó¼ÓÔÚlistÎ²²¿
		{
			gEmvballocator.EMVBallocator_memcpy(&dsttagdata[dsttagdatalen],&srctagdata[offset],i-offset+len);
			dsttagdatalen += i-offset+len;
		}
		
		
		//±È½ÏÏÂÒ»¸öTAG
		i += len;
		
		
    }
    
    emvblib_free(tempbuf);
	return dsttagdatalen;

	
}


void Paypassb_AddListToList(unsigned char *srctag,unsigned char *dsttag,unsigned char type)
{
    
	unsigned char *templist;//[512];
    unsigned int templen = 0;
    EMVTAGCVLITEM *srcitem;
	EMVTAGCVLITEM *dstitem;
	unsigned char *srcdata,*dstdata;
	unsigned int srcdatalen,dstdatalen;
	unsigned char updateflag = 0;
    
	
    srcitem = dllemvb_avl_gettagitempointer(srctag);
	dstitem = dllemvb_avl_gettagitempointer(dsttag);
	srcdata = NULL;
    dstdata = NULL;
	srcdatalen = 0;
	dstdatalen = 0;
	
	
    if(dstitem != NULL)
    {
		
    	if(dstitem->len)
    	{
    		dstdata = dstitem->data;
			dstdatalen = dstitem->len;
    	}
		
    }
	
    if(srcitem != NULL)
    {
		srcdata = srcitem->data;
		srcdatalen = srcitem->len;
    }

	 if(srcdata == NULL)
    {
    	return;
    }

    templist = (unsigned char *)emvblib_malloc(1024+128);
	if(templist == NULL)
	{
		return;
	}
	gEmvballocator.EMVBallocator_memset(templist,0,1024+128);
	if(dstdata != NULL)
	{
		gEmvballocator.EMVBallocator_memcpy(templist,dstdata,dstdatalen);
	}
    templen = Paypassb_AddListToList_Process(srcdata,srcdatalen,templist,dstdatalen,type);
	if(templen)
	{
		
		if(templen != dstdatalen)
		{
			updateflag = 1;
		}
		else
		{
			
			if(gEmvballocator.EMVBallocator_memcmp(dstdata,templist,templen))
			{
				updateflag = 1;
			}
			
		}
		
		
		if(updateflag)
		{
			dllemvb_avl_createsettagvalue(dsttag,templist,templen);
		}
		
	}

	emvblib_free(templist);
	
	
}


void Paypassb_AddListToList_withtagdata(unsigned char *srctag,unsigned char *srcdata,unsigned int srcdatalen,unsigned char *dsttag,unsigned char type)
{
    
	unsigned char *templist;//[512];
    unsigned int templen = 0;
	EMVTAGCVLITEM *dstitem;
	unsigned char *dstdata;
	unsigned int dstdatalen;
	unsigned char updateflag = 0;
    
	
	dstitem = dllemvb_avl_gettagitempointer(dsttag);
    dstdata = NULL;
	dstdatalen = 0;
	
	
    if(dstitem != NULL)
    {
		
    	if(dstitem->len)
    	{
    		dstdata = dstitem->data;
			dstdatalen = dstitem->len;
    	}
		
    }

	 if(srcdata == NULL||srctag == NULL||srcdatalen == 0)
    {
    	return;
    }

    templist = (unsigned char *)emvblib_malloc(1024+128);
	gEmvballocator.EMVBallocator_memset(templist,0,1024+128);
	if(dstdata != NULL)
	{
		gEmvballocator.EMVBallocator_memcpy(templist,dstdata,dstdatalen);
	}
    templen = Paypassb_AddListToList_Process(srcdata,srcdatalen,templist,dstdatalen,type);
	if(templen)
	{
		
		if(templen != dstdatalen)
		{
			updateflag = 1;
		}
		else if(dstdata == NULL)
		{
			updateflag = 1;
		}
		else
		{
			
			if(gEmvballocator.EMVBallocator_memcmp(dstdata,templist,templen))
			{
				updateflag = 1;
			}
			
		}
		
		
		if(updateflag)
		{
			dllemvb_avl_createsettagvalue(dsttag,templist,templen);
		}
		
	}

	emvblib_free(templist);
	
	
}



void Paypassb_AddListToList_T_T(unsigned char *srctag,unsigned char *dsttag)
{
	Paypassb_AddListToList(srctag,dsttag,DEKTAGTYPE_TAG);
}

void Paypassb_AddListToList_T_T_Withlen(unsigned char *srctag,unsigned char *dsttag)
{
	Paypassb_AddListToList(srctag,dsttag,DEKTAGTYPE_TAGANDLEN);
}


void Paypassb_AddListToList_TLV_TLV(unsigned char *srctag,unsigned char *dsttag)
{
	Paypassb_AddListToList(srctag,dsttag,DEKTAGTYPE_TAGANDDATA);
}

unsigned int Paypassb_AddTLVToList_RemoveTag_Process(unsigned char *srctagdata,unsigned int srctagdatalen,unsigned char *dsttagdata,unsigned int dsttagdatalen,unsigned char *saveddata,unsigned short *savedatalen)
{
	
	unsigned char taglen;
	unsigned short i,len,offset,updatedatalen,tagdatalen,k;
    unsigned char *tempbuf;//[512];
    int dstoffset;
	unsigned char tag[4];
	EMVTAGCVLITEM *emvitem;
	unsigned char *transbuf;


	*savedatalen = 0;

	tempbuf = (unsigned char *)emvblib_malloc(1024+128);
    for(i = 0;i < srctagdatalen;)
    {
    	
        offset = i;  //¿½±´Êý¾ÝµÄÆ«ÒÆ
		
        taglen = 0;
		if((srctagdata[i]&0x1f) == 0x1f)
		{
			
			taglen++;
			if(srctagdata[i+1]&0x80)
			{
				taglen++;
			}
			
		}
		taglen++;
		
		//tagdatalen
		gEmvballocator.EMVBallocator_memset(tag,0,sizeof(tag));
		gEmvballocator.EMVBallocator_memcpy(tag,&srctagdata[i],taglen);
		i += taglen;
		
        len = 0;
		emvitem = dllemvb_avl_gettagitempointer(tag);
		tagdatalen = 0;
		if(emvitem != NULL)
		{
			tagdatalen = emvitem->len;
		}
		
		if(tagdatalen)  // IsNotEmpty,Ìí¼Óµ½listÖÐ²¢ÒÆ³ý
		{
			
		    gEmvballocator.EMVBallocator_memcpy(tempbuf,&srctagdata[offset],taglen);
			if((tagdatalen&0x80)>0)				 //ÓÐÁ½¸ö×Ö½Ú
			{
				tempbuf[taglen++]=0x81;
				tempbuf[taglen++]=tagdatalen;   //Ö»ÓÐÒ»¸ö×Ö½Ú
			}
			else
			{
				tempbuf[taglen++]=tagdatalen;   //Ö»ÓÐÒ»¸ö×Ö½Ú
			}
			gEmvballocator.EMVBallocator_memcpy(&tempbuf[taglen],emvitem->data,tagdatalen);
			tagdatalen += taglen;

			
			//¼ì²édst listÖÐÊÇ·ñÒÑ¾­´æÔÚ
			dstoffset = Paypassb_CheckListTagExist(&srctagdata[offset],taglen,dsttagdata,dsttagdatalen,&updatedatalen,DEKTAGTYPE_TAGANDDATA);
			if(dstoffset >= 0) //tag ÒÑ¾­´æÔÚ
			{
			    if(tagdatalen == updatedatalen)
			    {
			    	//±È½ÏÊý¾ÝÊÇ·ñÒ»ÖÂ£¬²»Ò»ÖÂ²Å¸üÐÂ
			    	if(gEmvballocator.EMVBallocator_memcmp(&dsttagdata[dstoffset],tempbuf,updatedatalen))
			    	{
			    		gEmvballocator.EMVBallocator_memcpy(&dsttagdata[dstoffset],tempbuf,updatedatalen);
			    	}
					
			    }
				else   //¿Ï¶¨²»Ò»ÖÂ£¬ÐèÒª½øÐÐÊý¾Ý°áÒÆ
				{
					
				    transbuf = (unsigned char *)emvblib_malloc(1024+128);
					
					gEmvballocator.EMVBallocator_memcpy(transbuf,dsttagdata,dstoffset);
					k = dstoffset;
	                gEmvballocator.EMVBallocator_memcpy(&transbuf[k],tempbuf,tagdatalen);
					k += tagdatalen;
					gEmvballocator.EMVBallocator_memcpy(&transbuf[k],&dsttagdata[dstoffset+updatedatalen],dsttagdatalen-(dstoffset+updatedatalen));
					k += dsttagdatalen-(dstoffset+updatedatalen);
					dsttagdatalen = k;
					gEmvballocator.EMVBallocator_memcpy(dsttagdata,transbuf,dsttagdatalen);
					
					emvblib_free(transbuf);
					
				}
				
			}
			else //tag ²»´æÔÚ,Ö±½Ó¼ÓÔÚlistÎ²²¿
			{
				gEmvballocator.EMVBallocator_memcpy(&dsttagdata[dsttagdatalen],tempbuf,tagdatalen);
				dsttagdatalen += tagdatalen;
			}
			
		}

		if(tagdatalen == 0)
		{
			gEmvballocator.EMVBallocator_memcpy(&saveddata[*savedatalen],&srctagdata[offset],i-offset+len);
			*savedatalen  += i-offset+len;
		}
		
		
		//±È½ÏÏÂÒ»¸öTAG
		i += len;
		
		
    }
    
    emvblib_free(tempbuf);
	return dsttagdatalen;
}







//ÍùTAGÖÐÐ´Êý¾Ý£¬Í¬Ê±Çå³ý TAG
void Paypassb_AddTLVToList_RemoveTag(unsigned char *srctag,unsigned char *dsttag)
{
    
	unsigned char *templist;//[512];
    unsigned int templen = 0;
    EMVTAGCVLITEM *srcitem;
	EMVTAGCVLITEM *dstitem;
	unsigned char *srcdata,*dstdata;
	unsigned int srcdatalen,dstdatalen;
	unsigned char updateflag = 0;
	unsigned char *savedbuf;
	unsigned short savedbuflen = 0;
    
	
    srcitem = dllemvb_avl_gettagitempointer(srctag);
	dstitem = dllemvb_avl_gettagitempointer(dsttag);
	srcdata = NULL;
    dstdata = NULL;
	srcdatalen = 0;
	dstdatalen = 0;
	
	
    if(dstitem != NULL)
    {
		
    	if(dstitem->len)
    	{
    		dstdata = dstitem->data;
			dstdatalen = dstitem->len;
    	}
		
    }
	
    if(srcitem != NULL)
    {
		srcdata = srcitem->data;
		srcdatalen = srcitem->len;
    }

	 if(srcdata == NULL)
    {
    	return;
    }

    templist = (unsigned char *)emvblib_malloc(1024+128);
	gEmvballocator.EMVBallocator_memset(templist,0,1024);
	if(dstdata != NULL)
	{
		gEmvballocator.EMVBallocator_memcpy(templist,dstdata,dstdatalen);
	}

    savedbuf = (unsigned char *)emvblib_malloc(1024+128);


	
    templen = Paypassb_AddTLVToList_RemoveTag_Process(srcdata,srcdatalen,templist,dstdatalen,savedbuf,&savedbuflen);
	if(templen)
	{
		
		if(templen != dstdatalen)
		{
			updateflag = 1;
		}
		else
		{
			
			if(gEmvballocator.EMVBallocator_memcmp(dstdata,templist,templen))
			{
				updateflag = 1;
			}
			
		}
		
		
		if(updateflag)
		{
			dllemvb_avl_createsettagvalue(dsttag,templist,templen);
		}
		
	}
    
	
	if(savedbuflen != srcdatalen)
	{
		dllemvb_avl_createsettagvalue(srctag,savedbuf,savedbuflen);
	}
    
	emvblib_free(savedbuf);
	emvblib_free(templist);
	
}



void Paypassb_AddDataToList(unsigned char *tag,unsigned char *tagdata,unsigned short tagdatalen,unsigned char *dsttag,unsigned char type)
{
	
	unsigned char *templist;//[512];
	unsigned int templen = 0;
	EMVTAGCVLITEM *dstitem;
	unsigned char *srcdata,*dstdata;
	unsigned int srcdatalen,dstdatalen;
	unsigned char updateflag = 0,taglen;
	
	
	dstitem = dllemvb_avl_gettagitempointer(dsttag);
	srcdata = NULL;
	dstdata = NULL;
	srcdatalen = 0;
	dstdatalen = 0;
	
	
	if(dstitem != NULL)
	{
		
		if(dstitem->len)
		{
			dstdata = dstitem->data;
			dstdatalen = dstitem->len;
		}
		
	}
	
	//srcdata pack
	srcdata = (unsigned char *)emvblib_malloc(300);
	taglen = 0;
	if((tag[0]&0x1f) == 0x1f)
	{
		
		taglen++;
		if(tag[1]&0x80)
		{
			taglen++;
		}
		
	}
	taglen++;
	gEmvballocator.EMVBallocator_memcpy(srcdata,tag,taglen);
	srcdatalen += taglen;
	if(type != DEKTAGTYPE_TAG)
	{
		if(tagdata != NULL)        //ËùÓÐ±£´æµÄÊý¾Ý¶¼ÊÇTLV¸ñÊ½µÄ
		{
			if((tagdatalen&0x80)>0)				 //ÓÐÁ½¸ö×Ö½Ú
			{
				srcdata[srcdatalen++]=0x81;
				srcdata[srcdatalen++]=tagdatalen;   //Á½¸ö×Ö½ÚÊý¾Ý³¤¶È
			}
			else
			{
				srcdata[srcdatalen++]=tagdatalen;   //Ö»ÓÐÒ»¸ö×Ö½Ú
			}
			
			gEmvballocator.EMVBallocator_memcpy(&srcdata[srcdatalen],tagdata,tagdatalen);
			srcdatalen += tagdatalen;
		}
		else
		{
			srcdata[srcdatalen++] = 0;
		}
		
	}

    templist = (unsigned char *)emvblib_malloc(1024+128);
	gEmvballocator.EMVBallocator_memset(templist,0,1024+128);
	if(dstdata != NULL)
	{
		gEmvballocator.EMVBallocator_memcpy(templist,dstdata,dstdatalen);
	}
	#ifdef ZTPAYPASS_DEBUG
	//API_TraceHex(DBG_APP_INFO,"add list to list:src",srcdata,srcdatalen);
    //API_TraceHex(DBG_APP_INFO,"add list to list:dst",dstdata,dstdatalen);
	#endif
	
	templen = Paypassb_AddListToList_Process(srcdata,srcdatalen,templist,dstdatalen,type);
    #ifdef ZTPAYPASS_DEBUG
    //API_TraceHex(DBG_APP_INFO,"add list to list:dst",dstdata,templen);
	#endif
	if(templen)
	{
		
		if(templen != dstdatalen)
		{
			updateflag = 1;
		}
		else
		{
			
			if(gEmvballocator.EMVBallocator_memcmp(dstdata,templist,templen))
			{
				updateflag = 1;
			}
			
		}
		
		
		if(updateflag)
		{
			dllemvb_avl_createsettagvalue(dsttag,templist,templen);
		}
		
	}

	emvblib_free(srcdata);
	emvblib_free(templist);
	
}

void Paypassb_AddDataToList_T(unsigned char *tag,unsigned char *dsttag)
{
	Paypassb_AddDataToList(tag,NULL,0,dsttag,DEKTAGTYPE_TAG);
}


void Paypassb_AddDataToList_TLV(unsigned char *tag,unsigned char *tagdata,unsigned short tagdatalen,unsigned char *dsttag)
{
	Paypassb_AddDataToList(tag,tagdata,tagdatalen,dsttag,DEKTAGTYPE_TAGANDDATA);
}


unsigned char paypassb_GetAndRemoveFromList(unsigned char *listtag,unsigned char *tag,unsigned char *taglen,unsigned char *tagdata,unsigned short *tagdatalen)
{
	EMVTAGCVLITEM *emvitem;
	unsigned short index = 0;
	unsigned char *tempbuf;
	unsigned int tempbufdatalen;
	
	emvitem = dllemvb_avl_gettagitempointer(listtag);
	if(emvitem != NULL)
	{
		if(emvitem->len)
		{
			if((emvitem->data[0]&0x1f) == 0x1f)
			{
				index++;
				if(emvitem->data[1]&0x80)
				{
					index++;
				}
				
			}
			index++;
			
			*taglen = index;
			gEmvballocator.EMVBallocator_memcpy(tag,emvitem->data,index);

            *tagdatalen = 0;
			if(ParseExtLen(emvitem->data,&index,tagdatalen)== 0)
			{
				gEmvballocator.EMVBallocator_memcpy(tagdata,&emvitem->data[index],*tagdatalen);
			}
			if(index+(*tagdatalen) < emvitem->len)
			{
			    tempbufdatalen = emvitem->len-(index+(*tagdatalen));
			    tempbuf = (unsigned char *)emvblib_malloc(tempbufdatalen);
				 
				gEmvballocator.EMVBallocator_memcpy(tempbuf,&emvitem->data[index+(*tagdatalen)],tempbufdatalen);
				dllemvb_avl_createsettagvalue(listtag,tempbuf,tempbufdatalen);
				emvblib_free(tempbuf);
			}
			else
			{
				dllemvb_avl_createsettagvalue(listtag,NULL,0);
			}

			return 1;
			
		}
	}
    
	return 0;

	
}



unsigned int Paypassb_CheckPresent_AddTLVToList_RemoveTag_Process(unsigned char *srctagdata,unsigned int srctagdatalen,unsigned char *dsttagdata,unsigned int dsttagdatalen)
{
	
	unsigned char taglen;
	unsigned short i,len,offset,updatedatalen,tagdatalen,k;
    unsigned char *tempbuf;//[512];
    int dstoffset;
	unsigned char tag[4];
	EMVTAGCVLITEM *emvitem;
	unsigned char *transbuf;
	EMVTAGCVLITEM emvtagitem;

	tempbuf = (unsigned char *)emvblib_malloc(1024+128);
    for(i = 0;i < srctagdatalen;)
    {
    	
        offset = i;  //¿½±´Êý¾ÝµÄÆ«ÒÆ
		
        taglen = 0;
		if((srctagdata[i]&0x1f) == 0x1f)
		{
			
			taglen++;
			if(srctagdata[i+1]&0x80)
			{
				taglen++;
			}
			
		}
		taglen++;
		
		//tagdatalen
		gEmvballocator.EMVBallocator_memset(tag,0,sizeof(tag));
		gEmvballocator.EMVBallocator_memcpy(tag,&srctagdata[i],taglen);
		i += taglen;
		
        len = 0;
		emvitem = dllemvb_avl_gettagitempointer(tag);
		tagdatalen = 0;
		if(emvitem != NULL)  // check if present
		{
			tagdatalen = emvitem->len;
			
		    gEmvballocator.EMVBallocator_memcpy(tempbuf,&srctagdata[offset],taglen);
			if((tagdatalen&0x80)>0)				 //ÓÐÁ½¸ö×Ö½Ú
			{
				tempbuf[taglen++]=0x81;
				tempbuf[taglen++]=tagdatalen;   //Ö»ÓÐÒ»¸ö×Ö½Ú
			}
			else
			{
				tempbuf[taglen++]=tagdatalen;   //Ö»ÓÐÒ»¸ö×Ö½Ú
			}
			gEmvballocator.EMVBallocator_memcpy(&tempbuf[taglen],emvitem->data,tagdatalen);
			tagdatalen += taglen;

			
			
			
		}
		else
		{
		    // isKnown(T)
			if(EMVB_TagBaseLib_read(tag,taglen,TAGTYPE_PAYPASS,&emvtagitem) == 0)
			{
				//Paypassb_AddDataToList_TLV(tag,NULL,0,(unsigned char *)TAG_PaypassDataToSend);
				//gEmvballocator.EMVBallocator_memcpy(tempbuf,&srctagdata[offset],taglen);
				gEmvballocator.EMVBallocator_memcpy(tempbuf,&srctagdata[offset],taglen);
				tempbuf[taglen++] = 0;
				tagdatalen += taglen;
				
			}
			
		}
		
		
		
		
		//¼ì²édst listÖÐÊÇ·ñÒÑ¾­´æÔÚ
		dstoffset = Paypassb_CheckListTagExist(&srctagdata[offset],taglen,dsttagdata,dsttagdatalen,&updatedatalen,DEKTAGTYPE_TAGANDDATA);
		if(dstoffset >= 0) //tag ÒÑ¾­´æÔÚ
		{
		    if(tagdatalen == updatedatalen)
		    {
		    	//±È½ÏÊý¾ÝÊÇ·ñÒ»ÖÂ£¬²»Ò»ÖÂ²Å¸üÐÂ
		    	if(gEmvballocator.EMVBallocator_memcmp(&dsttagdata[dstoffset],tempbuf,updatedatalen))
		    	{
		    		gEmvballocator.EMVBallocator_memcpy(&dsttagdata[dstoffset],tempbuf,updatedatalen);
		    	}
				
		    }
			else   //¿Ï¶¨²»Ò»ÖÂ£¬ÐèÒª½øÐÐÊý¾Ý°áÒÆ
			{
				
			    transbuf = (unsigned char *)emvblib_malloc(1024+128);
				
				gEmvballocator.EMVBallocator_memcpy(transbuf,dsttagdata,dstoffset);
				k = dstoffset;
                gEmvballocator.EMVBallocator_memcpy(&transbuf[k],tempbuf,tagdatalen);
				k += tagdatalen;
				gEmvballocator.EMVBallocator_memcpy(&transbuf[k],&dsttagdata[dstoffset+updatedatalen],dsttagdatalen-(dstoffset+updatedatalen));
				k += dsttagdatalen-(dstoffset+updatedatalen);
				dsttagdatalen = k;
				gEmvballocator.EMVBallocator_memcpy(dsttagdata,transbuf,dsttagdatalen);
				
				emvblib_free(transbuf);
				
			}
			
		}
		else //tag ²»´æÔÚ,Ö±½Ó¼ÓÔÚlistÎ²²¿
		{
			gEmvballocator.EMVBallocator_memcpy(&dsttagdata[dsttagdatalen],tempbuf,tagdatalen);
			dsttagdatalen += tagdatalen;
		}
		
		
		
		//±È½ÏÏÂÒ»¸öTAG
		i += len;
		
		
    }

    emvblib_free(tempbuf);
	return dsttagdatalen;
	
}


void Paypassb_CheckPresent_AddTLVToList_RemoveTag(unsigned char *srctag,unsigned char *dsttag)
{
    
	unsigned char *templist;//[512];
    unsigned int templen = 0;
    EMVTAGCVLITEM *srcitem;
	EMVTAGCVLITEM *dstitem;
	unsigned char *srcdata,*dstdata;
	unsigned int srcdatalen,dstdatalen;
	unsigned char updateflag = 0;
	//unsigned char *savedbuf;
	//unsigned short savedbuflen = 0;
    
	
    srcitem = dllemvb_avl_gettagitempointer(srctag);
	dstitem = dllemvb_avl_gettagitempointer(dsttag);
	srcdata = NULL;
    dstdata = NULL;
	srcdatalen = 0;
	dstdatalen = 0;
	
	
    if(dstitem != NULL)
    {
		
    	if(dstitem->len)
    	{
    		dstdata = dstitem->data;
			dstdatalen = dstitem->len;
    	}
		
    }
	
    if(srcitem != NULL)
    {
		srcdata = srcitem->data;
		srcdatalen = srcitem->len;
    }

	 if(srcdata == NULL)
    {
    	return;
    }

    templist = (unsigned char *)emvblib_malloc(1024+128);
	gEmvballocator.EMVBallocator_memset(templist,0,1024+128);
	if(dstdata != NULL)
	{
		gEmvballocator.EMVBallocator_memcpy(templist,dstdata,dstdatalen);
	}

    //savedbuf = (unsigned char *)emvblib_malloc(512);


	
    templen = Paypassb_CheckPresent_AddTLVToList_RemoveTag_Process(srcdata,srcdatalen,templist,dstdatalen);
	if(templen)
	{
		
		if(templen != dstdatalen)
		{
			updateflag = 1;
		}
		else
		{
			
			if(gEmvballocator.EMVBallocator_memcmp(dstdata,templist,templen))
			{
				updateflag = 1;
			}
			
		}
		
		
		if(updateflag)
		{
			dllemvb_avl_createsettagvalue(dsttag,templist,templen);
		}
		
	}

	
	dllemvb_avl_createsettagvalue(srctag,NULL,0);
	
    
	//emvblib_free(savedbuf);
	emvblib_free(templist);
	
}



unsigned char Paypassb_checkifneedaddtodataneed(unsigned char *tag,unsigned char taglen)
{
	EMVTAGCVLITEM *item;
	EMVTAGCVLITEM finditem;
    unsigned char addtodataneed = 0;

	item = dllemvb_avl_gettagitempointer(tag);
	if(tag[0] == 0x9F&&(tag[1]>= 0x70&&tag[1]<= 0x79))
	{
		addtodataneed = 1;
	}
	else if(item != NULL)
    {
    	if(item->updatecondition&TAGUPDATECONDITION_DET) //DET tag add to data need
        {
			addtodataneed = 1;
        }
    }
    else if(EMVB_TagBaseLib_read(tag,taglen,TAGTYPE_PAYPASS,&finditem)==0)
    {
        if(finditem.updatecondition&TAGUPDATECONDITION_DET) //DET tag add to data need
        {
			addtodataneed = 1;
        }
    }

	if(addtodataneed)
	{
		Paypassb_AddDataToList_T(tag,(unsigned char *)TAG_PaypassDataNeeded);
	}

	return addtodataneed;
	
}



void Paypassb_DOL_CheckAddToList(unsigned char *DOL,unsigned char *addtag)
{
    EMVTAGCVLITEM *item;
	unsigned short index = 0;
	unsigned char tag[4],taglen;
	//int ret;
	
	item = dllemvb_avl_gettagitempointer(DOL);
	if(item != NULL)
	{	
		if(item->len)
		{
			while(index<item->len)//Process PDOL
			{
				gEmvballocator.EMVBallocator_memset(tag,0,sizeof(tag));
				taglen = 0;
				tag[taglen++] = item->data[index];
				if((tag[0]&0x1f) == 0x1f)
				{
					tag[taglen++] = item->data[index+1];
					if(tag[1]&0x80)
					{
						tag[taglen++] = item->data[index+2];
					}
				}
				
				
			    //if(dllemvb_avl_checkiftagexist(tag) == 0&&item->data[index+taglen] != 0)
			    if(dllemvb_avl_checkiftagempty(tag))
			    {
					Paypassb_AddDataToList_T(tag,(unsigned char *)TAG_PaypassDataNeeded);
			        //Paypassb_checkifneedaddtodataneed(tag,taglen);
			    }

				#ifdef ZTPAYPASS_DEBUG
				//API_TraceHex(DBG_APP_INFO,"add tag to need",tag,taglen);
                dllemvb_avl_printtagallvalue((unsigned char *)"tagneed 1",(unsigned char *)TAG_PaypassDataNeeded);
				#endif
				index += taglen+1;
				
			}
			
		}
	}
    
	
	
		
}






//20140222
unsigned char Paypassb_checkifwrongtag(EMVBAppUnionStruct *tempApp_UnionStruct,unsigned char *tag,unsigned char taglen,EMVTAGCVLITEM *retrunitem)
{
    
	//int i;
	unsigned char tagknown = 0;
	unsigned char present = 0;
	unsigned char empty = 1;
	unsigned char tagprivateclass = 0;
    unsigned char updateRA = 0;
	unsigned char temptag[4];
	unsigned char temptaglen;
    EMVTAGCVLITEM *item;
	unsigned char ret = 2;
	int ret1;
    
	//tag check  ºÍPAYPASS µÄ´¦ÀíÒª·Ö¿ª
    
	
    //ÏÈ²é¿´TREEÖÐÊÇ·ñ´æÔÚ
    gEmvballocator.EMVBallocator_memset(temptag,0,sizeof(temptag));
	temptaglen = (taglen>3)?3:(taglen);
	gEmvballocator.EMVBallocator_memcpy(temptag,tag,temptaglen);
    item = dllemvb_avl_gettagitempointer(temptag);
	if(item != NULL)
	{
		present = 1;
		if(item->SupAppType&TAGTYPE_PAYPASS)  //20131024ÐèÒª¼ì²éÒ»ÏÂ²åÈëÊ±µÄÇé¿ö
		{

		    //
			tagknown = 1;

		}
		updateRA = item->updatecondition&TAGUPDATECONDITION_RA;
		if(item->len)
		{
			empty = 0;
		}
		
	}
    
	if(present == 0)  //check if tag known
	{
		ret1 = EMVB_TagBaseLib_read(tag,taglen,TAGTYPE_PAYPASS,retrunitem);
        if(ret1 == 0)
        {
#if 0
        	tagknown = Paypassb_IfIDSTagCanKnown(tag, taglen);
        	if(tagknown)
        	{
        	    updateRA = retrunitem->updatecondition&TAGUPDATECONDITION_RA;
        	}
#else
        	tagknown = 1;
        	updateRA = retrunitem->updatecondition&TAGUPDATECONDITION_RA;
#endif
        }
		
	}
	else
	{
	    
		gEmvballocator.EMVBallocator_memcpy(retrunitem,item,sizeof(EMVTAGCVLITEM));
		
	}
    
    
	
	if((tag[0]&0xc0)== 0xc0)
	{
		tagprivateclass = 1;
	}
    
	
	#ifdef EMVB_DEBUG
    emvb_printf("\r\ntagstatus = %02x %02x %02x %02x %02x\r\n",tagknown,tagprivateclass,updateRA,present,empty);
	#endif

	if(!(tagknown&&tagprivateclass&&(updateRA == 0)))
	{
		if(tagknown)
		{
			if((present == 0||empty)&&updateRA)
			{
			    #ifdef EMVB_DEBUG
                emvb_printf("\r\nPaypass_checkifwrongtagok3\r\n");
				#endif
				ret = 1;
			}
			else
			{
			    #ifdef EMVB_DEBUG
                emvb_printf("\r\nPaypass_checkifwrongtaga\r\n");
				#endif
				ret = 0;
			}
		}
		else
		{
			if(present)
			{
				if(empty&&updateRA)
				{
				    #ifdef EMVB_DEBUG
                    emvb_printf("\r\nPaypass_checkifwrongtagokb\r\n");
					#endif
					ret = 1;
				}
				else
				{
				    #ifdef EMVB_DEBUG
	                emvb_printf("\r\nPaypass_checkifwrongtagc\r\n");
					#endif
					ret = 0;
				}
			}
		}
	}
    
    
	
	return ret;
}



//20140222
unsigned char Paypassb_ParseAndStoreCardResponse(EMVBAppUnionStruct *tempApp_UnionStruct,unsigned char *DataOut,unsigned short *DataOutIndex,unsigned char *parsebInTable,unsigned char readstep)
{
	//unsigned char i,k;
	unsigned short index,len;
	unsigned char tagindex;  //tmpdata,tmpval,,addvalue,ifemvtag
	unsigned char bInTable;
	unsigned char tag[4],taglen;
	unsigned char ret;
	//unsigned char needdonextstep = 1;
    EMVTAGCVLITEM tagitem;
	

	#ifdef EMVB1_DEBUG
    EMVTAGCVLITEM *item;
	unsigned char i;
	#endif
	
    index = *DataOutIndex;
    bInTable = 0;
    
	
	#ifdef EMVB1_DEBUG
    emvb_printf("\r\nindex111 = %d %d\r\n",index,bInTable);
	#endif

	if(DataOut[index] == 0xFF||DataOut[index] == 0x00)
	{
		 index++;
		*DataOutIndex = index;
	    *parsebInTable = bInTable;
		
		return EMV_OK;
	}
    
	
	gEmvballocator.EMVBallocator_memset(tag,0,sizeof(tag));
    taglen = 0;
    tag[taglen++] = DataOut[index];
	if((tag[0]&0x1f) == 0x1f)
	{
		tag[taglen++] = DataOut[index+1];
		if(tag[1]&0x80)
		{
			tag[taglen++] = DataOut[index+2];
		}
	}
    
	#ifdef EMVB1_DEBUG
    emvb_printf("\r\ntag:");
	for(i = 0;i < taglen;i++)
	{
		emvb_printf("%02x ",tag[i]);
	}
	emvb_printf("\r\n");
	#endif
    
    
	if(readstep == 1)
	{
		tagindex = 0;
		while((PaypassbReadrecordbadTag[tagindex][0] != 0)||(PaypassbReadrecordbadTag[tagindex][1] != 0) )
		{
		    if((PaypassbReadrecordbadTag[tagindex][0] == tag[0])&&(PaypassbReadrecordbadTag[tagindex][1] == tag[1]) )
		    {
				
		        return PAYPASS_CARDDATAERR;
		    }
			tagindex++;
		}

		
	}
    else if(readstep == 2)
	{
		tagindex = 0;
		while((PaypassbCCCbadTag[tagindex][0] != 0)||(PaypassbCCCbadTag[tagindex][1] != 0) )
		{
		    if((PaypassbCCCbadTag[tagindex][0] == tag[0])&&(PaypassbCCCbadTag[tagindex][1] == tag[1]) )
		    {
				
		        return ERR_EMV_IccDataFormat;
		    }
			tagindex++;
		}
	}
	else if(readstep == 3)
	{
		tagindex = 0;
		while((PaypassbReadrecordformatbadTag[tagindex][0] != 0)||(PaypassbReadrecordformatbadTag[tagindex][1] != 0) )
		{
		    if((PaypassbReadrecordformatbadTag[tagindex][0] == tag[0])&&(PaypassbReadrecordformatbadTag[tagindex][1] == tag[1]) )
		    {
				
		        return ERR_EMV_IccDataFormat;
		    }
			tagindex++;
		}
	}
	else if(readstep == 4)
	{
		tagindex = 0;
		while((PaypassbGACbadTag[tagindex][0] != 0)||(PaypassbGACbadTag[tagindex][1] != 0) )
		{
		    if((PaypassbGACbadTag[tagindex][0] == tag[0])&&(PaypassbGACbadTag[tagindex][1] == tag[1]) )
		    {
				
		        return ERR_EMV_IccDataFormat;
		    }
			tagindex++;
		}
	}
	else if(readstep == 5)
	{
		tagindex = 0;
		while((PaypassbFinselectA5badTag[tagindex][0] != 0)||(PaypassbFinselectA5badTag[tagindex][1] != 0) )
		{
		    if((PaypassbFinselectA5badTag[tagindex][0] == tag[0])&&(PaypassbFinselectA5badTag[tagindex][1] == tag[1]) )
		    {
				
		        return ERR_EMV_IccDataFormat;
		    }
			tagindex++;
		}
	}
	else if(readstep == 6)
	{
		tagindex = 0;
		while((PaypassbFinselectbf0cbadTag[tagindex][0] != 0)||(PaypassbFinselectbf0cbadTag[tagindex][1] != 0) )
		{
		    if((PaypassbFinselectbf0cbadTag[tagindex][0] == tag[0])&&(PaypassbFinselectbf0cbadTag[tagindex][1] == tag[1]) )
		    {
				
		        return ERR_EMV_IccDataFormat;
		    }
			tagindex++;
		}
	}
	else if(readstep == 7)
	{
		tagindex = 0;
		while((PaypassbFinselectbadTag[tagindex][0] != 0)||(PaypassbFinselectbadTag[tagindex][1] != 0) )
		{
		    if((PaypassbFinselectbadTag[tagindex][0] == tag[0])&&(PaypassbFinselectbadTag[tagindex][1] == tag[1]) )
		    {
				
		        return ERR_EMV_IccDataFormat;
		    }
			tagindex++;
		}
	}

	
	ret = Paypassb_checkifwrongtag(tempApp_UnionStruct,tag,taglen,&tagitem);
	#ifdef EMVB_DEBUG
    emvb_printf("\r\nret123 = %d\r\n",ret);
	#endif
	if(ret == 0)
    {
        #ifdef EMVB_DEBUG
        emvb_printf("\r\n%02x %02x wrong tag1\r\n",tag[0],tag[1]);
		#endif
    	return ERR_EMV_IccDataFormat;
    }
	else if(ret == 2)
	{
	    //needdonextstep = 0;
	}
    else
    {
		index += taglen;
        if(ParseExtLen(DataOut,&index,&len))
		{
		    
			#ifdef EMVB_DEBUG
			emvb_printf("\r\nEmv_PaypassReadAFLRetData122313 %d\r\n",index);
			#endif
			return ERR_EMV_IccDataFormat;
		}

        
		if(len)
		{
			if((len > tagitem.maxlen || len < tagitem.minlen)&&(tagitem.SupAppType&TAGTYPE_PAYPASS))
			{
			    #ifdef EMVB_DEBUG
				emvb_printf("\r\nEmv_PaypassReadAFLRetData122312df %d %d %d %d\r\n",len,tagitem.maxlen,tagitem.minlen);
				#endif
				return ERR_EMV_IccDataFormat;
			}
		}

		#ifdef EMVB1_DEBUG
	    emvb_printf("\r\ninsert tag:");
		for(i = 0;i < taglen;i++)
		{
			emvb_printf("%02x ",tag[i]);
		}
		emvb_printf("\r\n");
        
		
		
		for(i = 0;i < len;i++)
		{
			emvb_printf("%02x ",DataOut[index + i]);
		}
		emvb_printf("\r\n");
		
		#endif
        if(tempApp_UnionStruct->EMVTradeParam->paypassgetdataflag)
        {
        	
        	if(gEmvballocator.EMVBallocator_memcmp(tempApp_UnionStruct->EMVTradeParam->paypassgetdatatag,tag,taglen))
        	{
        		return ERR_EMV_IccDataFormat;
        	}
			//S5.23  //²»²åÈëµ½Êý¾Ý¿âÖÐ
			dllemvb_avl_insert(&tagitem,tag,strlen((char *)tag),&DataOut[index],len,NULL);
			Paypassb_AddDataToList_TLV(tag,&DataOut[index],len,(unsigned char *)TAG_PaypassDataToSend);
			
        }
		else
		{
        	dllemvb_avl_insert(&tagitem,tag,gEmvballocator.EMVBallocator_strlen((char *)tag),&DataOut[index],len,NULL);
		}
        
		#ifdef EMVB1_DEBUG
		/*
        if(gEmvballocator.EMVBallocator_memcmp(tag,"\x9F\x36",2) == 0)
        {
        	emvb_printf("\r\ncheck ATC tag\r\n");
			item = dllemvb_avl_gettagitempointer(TAG_ATC);
			if(item != NULL)
			{
				if(item->len)
				{
					emvb_printf("\r\nATC tag exist %d\r\n",dllemvb_avl_checkiftagexist(TAG_ATC));
				}
			}
        }
		emvb_printf("\r\nATC tag exist %d\r\n",dllemvb_avl_checkiftagexist(TAG_ATC));
		*/
		//print_whole_tree();
		

		#endif
        
		
        
		index += len;
		bInTable = 1;
    }

	#ifdef EMVB1_DEBUG
    emvb_printf("\r\nbInTable = %d\r\n",index);
	#endif
		
	
	if(bInTable == 0)
	{
		index += taglen;
        
		if(ParseExtLen(DataOut,&index,&len))
		{
		    
			#ifdef EMVB1_DEBUG
			emvb_printf("\r\nEmv_PaypassReadAFLRetData121313 %d\r\n",index);
			#endif
			return ERR_EMV_IccDataFormat;
		}
        index += len;
        
		bInTable = 1;
	}
    
	#ifdef EMVB1_DEBUG
    emvb_printf("\r\nindex = %d %d\r\n",index,bInTable);
	#endif
	
    *DataOutIndex = index;
    *parsebInTable = bInTable;
	
	return EMV_OK;
}


//20140222
void Paypassb_saveFCIdata(EMVBAppUnionStruct *tempApp_UnionStruct,LISTAPPDATA *tempselectedapp,APDU_RESP *Termapdu_r)
{
	OUTPARAMETERSET *tempoutparameterset;
	tempoutparameterset = tempApp_UnionStruct->pOutParameterSet;
    
    
    if(tempApp_UnionStruct->EMVTradeParam->SelectSuccessoutmsg)
    {
	    tempoutparameterset->FCIdatalen = Termapdu_r->LenOut;
		gEmvballocator.EMVBallocator_memcpy(tempoutparameterset->FCIdata,Termapdu_r->DataOut,tempoutparameterset->FCIdatalen);
		tempoutparameterset->SelectCombDatalen = tempselectedapp->AIDLen;
		gEmvballocator.EMVBallocator_memcpy(tempoutparameterset->SelectCombData,tempselectedapp->AID,tempselectedapp->AIDLen);
		tempoutparameterset->SelectCombData[tempoutparameterset->SelectCombDatalen] = tempselectedapp->ReqKernelID;
		tempoutparameterset->SelectCombDatalen += 1;
        
	    tempoutparameterset->selectsucdata = 1;
    }
	else
	{
		tempoutparameterset->selectsucdata = 0;
	}
    
	
}


//20140222
void Paypassb_direcionaryiteminit(EMVBAppUnionStruct *tempApp_UnionStruct)
{
    
	OUTPARAMETERSET *tempoutparameterset;
    
	tempoutparameterset = tempApp_UnionStruct->pOutParameterSet;
    
	gEmvballocator.EMVBallocator_memset(&tempoutparameterset->discretionaryitem,0,sizeof(DISCRETIONARYITEMITEM));
    
	
}




//20140222
void Paypassb_packoutsignal(EMVBAppUnionStruct *tempApp_UnionStruct,unsigned int step)
{

    unsigned char temp[10];

	
    OUTPARAMETERSET *tempoutparameterset;
	ERRORID *temperrid;
	USERINTERFACEREQDATA *tempuserinterfacereqdata;
	//APDU_RESP *tempapduresp;
    EMVBERRORID *tempEmvErrID;
	PHONEMESSAGETABLEINFO *tempphonemsgtbl;
    
	tempoutparameterset = tempApp_UnionStruct->pOutParameterSet;
	temperrid = tempApp_UnionStruct->pErrorID;
	tempuserinterfacereqdata = tempApp_UnionStruct->pUserInterfaceReqData;
    tempEmvErrID = tempApp_UnionStruct->EmvErrID;
	tempphonemsgtbl = tempApp_UnionStruct->pphonemsgtable;
    
    gEmvballocator.EMVBallocator_memset(temp,0,sizeof(temp));
    #ifdef EMVB_DEBUG
    emvb_printf("\r\nsignal step = %d\r\n",step);
	#endif
    
	if(step == PAYPASSSTEP_S53_8)
	{
	    if(tempApp_UnionStruct->EMVTradeParam->SelectSuccessoutmsg)
	    {
			tempoutparameterset->opssendflag = 1;
			tempoutparameterset->DisDataPresent = 1;
	    }
	}
    else if(step == PAYPASSSTEP_S11_E120_2)
    {
        tempoutparameterset->UIRequestOnOutPresent = 1;
		
    	tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
		tempoutparameterset->DataRecordPresent = 1;

		tempuserinterfacereqdata->sendMsgFlag = 1;
		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.emvdataflag = 1;
    }
	else if(step == PAYPASSSTEP_S4_E13_0)
	{
		tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		temperrid->L3 = PAYPASS_ERRID_L3_AMOUNTNOTPRESENT;

		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.emvdataflag = 1;
	}
	else if(step == PAYPASSSTEP_S11_E120_1)
	{
	    tempuserinterfacereqdata->MessageID = tempoutparameterset->status;
		tempoutparameterset->UIRequestOnRestartPresent = 1;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_READYTOREAD;
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,"\x00\x00\x00",3);
        tempuserinterfacereqdata->MessageID = tempphonemsgtbl->phonemessagetable[tempApp_UnionStruct->EMVTradeParam->PaypassSelectedPOSCIIID].MESSAGE;
		
		tempuserinterfacereqdata->sendMsgFlag = 1;  
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
		tempoutparameterset->DataRecordPresent = 1;

		#ifdef EMVB_DEBUG
        emvb_printf("\r\ntempuserinterfacereqdata->sendMsgFlagaaa\r\n = %d\r\n",tempuserinterfacereqdata->sendMsgFlag);
		#endif
	}
    else if(step == PAYPASSSTEP_S11_E114_5)
    {
    	tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
    }
    else if(step == PAYPASSSTEP_S11_E114_4)
    {
    	tempoutparameterset->status = PAYPASS_OPS_STATUS_TRYANOTHERINTERFACE;
    }
    else if(step == PAYPASSSTEP_S11_E114_3)
    {
    	tempoutparameterset->status = PAYPASS_OPS_STATUS_DECLINED;
    }
    else if(step == PAYPASSSTEP_S11_E114_2)
    {
    	tempoutparameterset->status = PAYPASS_OPS_STATUS_ONLINE;
    }
	else if(step == PAYPASSSTEP_S11_E114_1)
	{
		tempoutparameterset->status = PAYPASS_OPS_STATUS_APPROVED;
	}
    else if(step == PAYPASSSTEP_S11_E112_0)
    {
    	tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		tempoutparameterset->start = PAYPASS_OPS_START_B;
    }
    else if(step == PAYPASSSTEP_S11_E110_0)
    {
    	tempoutparameterset->DataRecordPresent = 1;
    }
    else if(step == PAYPASSSTEP_S5_E27_2)
    {
    	tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		temperrid->MsgOnError = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		temperrid->L2 = PAYPASS_ERRID_L2_CARDDATAERR;
        tempoutparameterset->UIRequestOnOutPresent = 1;  //?  2017 ¶¼Òª¼ì²éÒ»ÏÂ
		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.errindicationflag = 1;
		tempuserinterfacereqdata->sendMsgFlag = 1;
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
		
    }
	else if(step == PAYPASSSTEP_S51_12_0)
	{   
	    
		tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		temperrid->MsgOnError = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		temperrid->L2 = PAYPASS_ERRID_L2_EMPTYCANLIST;
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
		tempoutparameterset->UIRequestOnOutPresent = 1;   //sx2017
        tempuserinterfacereqdata->sendMsgFlag = 1;
		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.errindicationflag = 1;
		
	}
	else if(step == PAYPASSSTEP_S52_13)
	{
	    temperrid->L3 = PAYPASS_ERRID_L3_STOP;
		tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;

		tempoutparameterset->discretionaryitem.errindicationflag = 0;
		
	}
	else if(step == PAYPASSSTEP_S7_8)
	{
		temperrid->L3 = PAYPASS_ERRID_L3_STOP;
		tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;

		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
	}
	else if(step == PAYPASSSTEP_S2_3_0)
	{
		temperrid->L3 = EMVB_ERRID_L3_TIMEOUT;
		tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;

		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
	}
	else if(step == PAYPASSSTEP_S2_4_0)
	{
		temperrid->L3 = EMVB_ERRID_L3_STOP;
	}
	else if(step == PAYPASSSTEP_S16_E7)
	{
		temperrid->L3 = PAYPASS_ERRID_L3_STOP;
		tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;

		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.emvdataflag = 1;
	}
	else if(step == PAYPASSSTEP_S9_E15_0)
	{
		tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		tempoutparameterset->start = PAYPASS_OPS_START_B;
		tempoutparameterset->UIRequestOnRestartPresent = 1;
		temperrid->L1 = 1;
		temperrid->MsgOnError = PAYPASS_USERREQDATA_MSGID_TRYAGAIN;

		tempuserinterfacereqdata->sendMsgFlag = 1;  
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
        
		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.emvdataflag = 1;
	}
    else if(step == PAYPASSSTEP_S11_E95_0)
    {
    	tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		temperrid->MsgOnError = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;

		tempoutparameterset->UIRequestOnOutPresent = 1;
        tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
		tempuserinterfacereqdata->sendMsgFlag = 1;
		
		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.emvdataflag = 1;
    }
    else if(step == PAYPASSSTEP_S9_E10_0)
    {
        
    	tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		tempoutparameterset->start = PAYPASS_OPS_START_B;
		tempoutparameterset->UIRequestOnRestartPresent = 1;
		temperrid->L1 = 1;
		temperrid->MsgOnError = PAYPASS_USERREQDATA_MSGID_TRYAGAIN;
        
		tempuserinterfacereqdata->sendMsgFlag = 1;  
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
        
		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.emvdataflag = 1;
		
    }
	else if(step == PAYPASSSTEP_S9_8)
	{
		tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		temperrid->MsgOnError = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		temperrid->L1 = 1;
        tempoutparameterset->UIRequestOnOutPresent = 1;
		
		tempoutparameterset->DataRecordPresent = 1;
        tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
		tempuserinterfacereqdata->sendMsgFlag = 1; 
		
		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.emvdataflag = 1;
		
	}
	else if(step == PAYPASSSTEP_S11_101)
	{
		
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,PAYPASS_USERREQDATA_MSGHOLDTIME_DEFAULT,3);
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_NOTREADY;
		tempuserinterfacereqdata->sendMsgFlag = 1;
		
		tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		temperrid->MsgOnError = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		tempoutparameterset->UIRequestOnOutPresent = 1;
		
		//tempoutparameterset->DataRecordPresent = 1;
        tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;

		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.emvdataflag = 1;
		
	}
	else if(step == PAYPASSSTEP_S10_E52_0)
	{
		tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		temperrid->MsgOnError = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		tempoutparameterset->UIRequestOnOutPresent = 1;
		
		tempoutparameterset->DataRecordPresent = 1;
        tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
        tempuserinterfacereqdata->sendMsgFlag = 1;
		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.emvdataflag = 1;
	}
    else if(step == PAYPASSSTEP_S10_E53_0)
    {
    	tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		temperrid->MsgOnError = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
        tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
		tempoutparameterset->UIRequestOnOutPresent = 1;
        tempuserinterfacereqdata->sendMsgFlag = 1;
		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.emvdataflag = 1;
		
    }
    else if(step == PAYPASSSTEP_S10_E6_0)
    {
    	tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		tempoutparameterset->start = PAYPASS_OPS_START_B;
		tempoutparameterset->UIRequestOnRestartPresent = 1;
		temperrid->L1 = 1;
		temperrid->MsgOnError = PAYPASS_USERREQDATA_MSGID_TRYAGAIN;
        
		//temperrid->MsgOnError = PAYPASS_ERRID_MSGONERR_TRYAGAIN;
		tempuserinterfacereqdata->sendMsgFlag = 1;  
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;

		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.emvdataflag = 1;
    }
    else if(step == PAYPASSSTEP_S14_33_0)
    {
    	tempoutparameterset->status = PAYPASS_OPS_STATUS_ONLINE;
		tempoutparameterset->CVM = PAYPASS_OPS_CVM_NOCVMREQ;
		tempoutparameterset->DataRecordPresent = 1;
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;

		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.msgdataflag= 1;
    }
	else if(step == PAYPASSSTEP_S14_34_0)
	{
		tempoutparameterset->status = PAYPASS_OPS_STATUS_ONLINE;
		tempoutparameterset->CVM = PAYPASS_OPS_CVM_CONFVERIFIED;
        if(tempApp_UnionStruct->EMVTradeParam->ContactlessCVMRLEF)
        {
        	tempoutparameterset->ReceiptinoutParameter = 1;
        }
		tempoutparameterset->DataRecordPresent = 1;
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;

		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.msgdataflag= 1;
	}
	else if(step == PAYPASSSTEP_S13_26_0)
    {
        
    	tempoutparameterset->status = PAYPASS_OPS_STATUS_ONLINE;
		dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_TermCapab,temp,1,1);
		#ifdef EMVB_DEBUG
        emvb_printf("\r\ntempterminfo->TermCapab[1]1 = %02x\r\n",temp[0]);
		#endif
		tempoutparameterset->CVM = temp[0]>>4;          //ÕâÀïÐèÒªÈ¡Êµ¼ÊµÄCVM·½Ê½
		tempoutparameterset->ReceiptinoutParameter = 1;
		tempoutparameterset->DataRecordPresent = 1;

		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
        tempApp_UnionStruct->EMVTradeParam->bPrintReceipt = 1;
		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.msgdataflag= 1;
		
    }
    else if(step == PAYPASSSTEP_S13_25_0)
	{
	    tempoutparameterset->status = PAYPASS_OPS_STATUS_ONLINE;
		dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_TermCapab,temp,1,1);
		tempoutparameterset->CVM = temp[0]>>4;
		#ifdef EMVB_DEBUG
        emvb_printf("\r\ntempterminfo->TermCapab[1] = %02x\r\n",temp[0]);
		#endif
		if((temp[0]&0xf0) == 0x10)
		{
			tempoutparameterset->ReceiptinoutParameter = 1;
			tempoutparameterset->CVM = PAYPASS_OPS_CVM_OBTAINSIGNATURE;
			tempApp_UnionStruct->EMVTradeParam->bPrintReceipt = 1;
		}
		tempoutparameterset->DataRecordPresent = 1;
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
        
		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.msgdataflag= 1;
	}
    else if(step == PAYPASSSTEP_S13_33_0)
    {
    	tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		temperrid->MsgOnError = tempuserinterfacereqdata->MessageID;
        
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
		tempoutparameterset->UIRequestOnOutPresent = 1;
        tempuserinterfacereqdata->sendMsgFlag = 1;
		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.msgdataflag= 1;
    }
    else if(step == PAYPASSSTEP_S13_45_0)
    {
		
		tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		tempoutparameterset->start = PAYPASS_OPS_START_B;
		tempoutparameterset->UIRequestOnRestartPresent = 1;
		tempoutparameterset->DataRecordPresent = 1;
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
		tempuserinterfacereqdata->sendMsgFlag = 1;

		tempuserinterfacereqdata->MessageID = tempphonemsgtbl->phonemessagetable[tempApp_UnionStruct->EMVTradeParam->PaypassSelectedPOSCIIID].MESSAGE;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_READYTOREAD;
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,"\x00\x00\x00",3);
		//tempuserinterfacereqdata->MessageID = tempoutparameterset->status;

		
		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.msgdataflag= 1;
    }
    else if(step == PAYPASSSTEP_S13_43_0)
    {
    	tempoutparameterset->status = PAYPASS_OPS_STATUS_DECLINED;
		tempoutparameterset->UIRequestOnOutPresent = 1;
		tempoutparameterset->DataRecordPresent = 1;
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
        tempuserinterfacereqdata->sendMsgFlag = 1;
		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.msgdataflag= 1;
    }
	else if(step == PAYPASSSTEP_S13_5_0)
	{
		tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		tempoutparameterset->start = PAYPASS_OPS_START_B;
		tempoutparameterset->UIRequestOnRestartPresent = 1;
		temperrid->L1 = 1;
		temperrid->MsgOnError = PAYPASS_USERREQDATA_MSGID_TRYAGAIN;

		tempuserinterfacereqdata->sendMsgFlag = 1;  
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
	}
    else if(step == PAYPASSSTEP_S16_E3_0)
    {
    	tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		tempoutparameterset->start = PAYPASS_OPS_START_B;
		tempoutparameterset->UIRequestOnRestartPresent = 1;
		temperrid->L1 = 1;
		temperrid->MsgOnError = PAYPASS_USERREQDATA_MSGID_TRYAGAIN;
        
        
		tempuserinterfacereqdata->sendMsgFlag = 1;  
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;

		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.emvdataflag = 1;
    }
    else if(step == PAYPASSSTEP_S5_E17_2)
    {
    	tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		temperrid->MsgOnError = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		temperrid->L2 = PAYPASS_ERRID_L2_CARDDATAMISSING;
        tempoutparameterset->UIRequestOnOutPresent = 1;
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
        tempuserinterfacereqdata->sendMsgFlag = 1;
		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.emvdataflag = 1;
    }
	else if(step == PAYPASSSTEP_GAC_13)
	{
		tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		temperrid->MsgOnError = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
        tempoutparameterset->UIRequestOnOutPresent = 1;
		
        tempuserinterfacereqdata->sendMsgFlag = 1;  
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;

		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.emvdataflag = 1;
		
	}
    else if(step == PAYPASSSTEP_S4_E27_2)
    {
    	tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		temperrid->MsgOnError = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		temperrid->L2 = PAYPASS_ERRID_L2_PARSINGERROR;
		tempoutparameterset->UIRequestOnOutPresent = 1;
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
        tempuserinterfacereqdata->sendMsgFlag = 1;
		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.emvdataflag = 1;
    }
	else if(step == PAYPASSSTEP_S4_E15_0)
	{
		tempoutparameterset->FieldoffinoutParameter = 0xff;
    	tempoutparameterset->status = PAYPASS_OPS_STATUS_SELECTNEXT;
		tempoutparameterset->start = PAYPASS_OPS_START_C;
        
		temperrid->L2 = PAYPASS_ERRID_L2_MAXLIMITEXCEEDED;
		
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;

		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.emvdataflag = 1;
	}
	else if(step == PAYPASSSTEP_S4_E10_2)
	{
		tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		temperrid->MsgOnError = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		temperrid->L2 = PAYPASS_ERRID_L2_STATUSBYTES;
		temperrid->SW12[0] = tempEmvErrID->SW12[0];
		temperrid->SW12[1] = tempEmvErrID->SW12[1];
        tempoutparameterset->UIRequestOnOutPresent = 1;
		
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
		tempuserinterfacereqdata->sendMsgFlag = 1;

		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.emvdataflag = 1;
	}
    else if(step == PAYPASSSTEP_S4_E6_0)
    {
    	tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		tempoutparameterset->start = PAYPASS_OPS_START_B;
		tempoutparameterset->UIRequestOnRestartPresent = 1;
		temperrid->L1 = 1;
		temperrid->MsgOnError = PAYPASS_USERREQDATA_MSGID_TRYAGAIN;
		tempuserinterfacereqdata->sendMsgFlag = 1;  
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;

		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.emvdataflag = 1;
    }
    else if(step == PAYPASSSTEP_S3_90_2)
    {
    	tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		temperrid->MsgOnError = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		tempoutparameterset->UIRequestOnOutPresent = 1;
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
        tempuserinterfacereqdata->sendMsgFlag = 1;
		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.errindicationflag = 1;
    }
    else if(step == PAYPASSSTEP_S3_9_2)
    {
        tempoutparameterset->FieldoffinoutParameter = 0xFF;
    	tempoutparameterset->status = PAYPASS_OPS_STATUS_SELECTNEXT;
		tempoutparameterset->start = PAYPASS_OPS_START_C;
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;

		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.errindicationflag = 1;
    }
    else if(step == PAYPASSSTEP_S3_5_0)
    {
    	tempoutparameterset->status = PAYPASS_OPS_STATUS_TRYAGAIN;
		tempoutparameterset->start = PAYPASS_OPS_START_B;
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
		
		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.errindicationflag = 1;
    }
    else if(step == PAYPASSSTEP_S1_8_0)
    {
    	tempoutparameterset->status = PAYPASS_OPS_STATUS_SELECTNEXT;
		tempoutparameterset->start = PAYPASS_OPS_START_C;

		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
		
		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.errindicationflag = 1;
    }
    else if(step == PAYPASSSTEP_S53_15)
    {
    	tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		temperrid->MsgOnError = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
		tempoutparameterset->UIRequestOnOutPresent = 1;
		tempuserinterfacereqdata->sendMsgFlag = 1;
    }
    else if(step == PAYPASSSTEP_S53_5)
	{
		tempoutparameterset->status = PAYPASS_OPS_STATUS_TRYAGAIN;
		tempoutparameterset->start = PAYPASS_OPS_START_B;
		temperrid->L1 = 1;
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
	}
	else if(step == PAYPASSSTEP_S52_19)
	{
		temperrid->MsgOnError = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		tempoutparameterset->UIRequestOnOutPresent =1;
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
		tempuserinterfacereqdata->sendMsgFlag = 1;
	}
	else if(step == PAYPASSSTEP_S52_9)
	{
		temperrid->MsgOnError = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		tempoutparameterset->UIRequestOnOutPresent = 1;
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
		tempuserinterfacereqdata->sendMsgFlag = 1;
	}
	else if(step == PAYPASSSTEP_S52_5)
	{
	    temperrid->L1 = 1;
		tempoutparameterset->status = PAYPASS_OPS_STATUS_TRYAGAIN;
		tempoutparameterset->start = PAYPASS_OPS_START_B;
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
	}
	else if(step == PAYPASSSTEP_SR1_5_2)
    {
		tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		tempoutparameterset->start = PAYPASS_OPS_START_B;
		tempoutparameterset->UIRequestOnRestartPresent = 1;
		temperrid->L1 = 1;
		temperrid->MsgOnError = PAYPASS_USERREQDATA_MSGID_TRYAGAIN;
	    
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;

		tempuserinterfacereqdata->sendMsgFlag = 1;
		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.emvdataflag = 1;
    }
	else if(step == PAYPASSSTEP_SR1_13)
	{
		tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		temperrid->MsgOnError = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		temperrid->L2 = PAYPASS_ERRID_L2_STATUSBYTES;
		temperrid->SW12[0] = tempEmvErrID->SW12[0];
		temperrid->SW12[1] = tempEmvErrID->SW12[1];
		
		tempoutparameterset->UIRequestOnOutPresent = 1;
		
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
		tempuserinterfacereqdata->sendMsgFlag = 1;
		
		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.emvdataflag = 1;
	}
	else if(step == PAYPASSSTEP_SR1_17)
	{
		tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		temperrid->MsgOnError = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		temperrid->L2 = PAYPASS_ERRID_L2_PARSINGERROR;
		
		tempoutparameterset->UIRequestOnOutPresent = 1;
		
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
		tempuserinterfacereqdata->sendMsgFlag = 1;
		
		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.emvdataflag = 1;
	}
	
    else if(step == PAYPASSSTEP_SR1_21)  // ||step == PAYPASSSTEP_S6_20_2
    {
    	tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		temperrid->MsgOnError = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		temperrid->L2 = PAYPASS_ERRID_L2_CARDDATAERR;
		
		tempoutparameterset->UIRequestOnOutPresent = 1;
		
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
		tempuserinterfacereqdata->sendMsgFlag = 1;
		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.emvdataflag = 1;
    }
    else if(step == PAYPASSSTEP_S5_6||step == PAYPASSSTEP_S12_6)
    {
    	tempoutparameterset->status = PAYPASS_OPS_STATUS_ENDAPPLICATION;
		tempoutparameterset->start = PAYPASS_OPS_START_B;
		tempoutparameterset->UIRequestOnRestartPresent = 1;
		temperrid->L1 = 1;
		temperrid->MsgOnError = PAYPASS_USERREQDATA_MSGID_TRYAGAIN;
	    
		tempoutparameterset->opssendflag = 1;
		tempoutparameterset->DisDataPresent = 1;
		tempuserinterfacereqdata->sendMsgFlag = 1;
		
		Paypassb_direcionaryiteminit(tempApp_UnionStruct);
		tempoutparameterset->discretionaryitem.emvdataflag = 1;
    }
	
   //if(tempuserinterfacereqdata->sendMsgFlag)
   //{
   		
   //}
    
	
	if(tempoutparameterset->DataRecordPresent == 0)
	{
		if(tempoutparameterset->opssendflag)
		{
			tempApp_UnionStruct->sendoutparamset(step);
			if(tempoutparameterset->DisDataPresent)
			{
				tempApp_UnionStruct->sendDisData();
			}

			tempoutparameterset->opssendflag = 0;
			tempoutparameterset->DisDataPresent = 0;
		}
		
		if(tempuserinterfacereqdata->sendMsgFlag)
		{
			tempApp_UnionStruct->senduserinterfacerequestdata(step);  
		}
		
		tempuserinterfacereqdata->sendMsgFlag = 0;
	}
	else
	{
		if(tempoutparameterset->status != PAYPASS_OPS_STATUS_APPROVED && tempoutparameterset->status != PAYPASS_OPS_STATUS_DECLINED &&
			tempoutparameterset->status != PAYPASS_OPS_STATUS_ONLINE)
		{
		    #ifdef EMVB_DEBUG
            emvb_printf("\r\ntempuserinterfacereqdata->sendMsgFlagkkk\r\n = %d\r\n",tempuserinterfacereqdata->sendMsgFlag);
			#endif
			if(tempoutparameterset->opssendflag)
			{
				
				tempApp_UnionStruct->sendoutparamset(step);

				
                #ifdef EMVB_DEBUG
	            emvb_printf("\r\ntempuserinterfacereqdata->sendMsgFlagzzzz\r\n = %d\r\n",tempuserinterfacereqdata->sendMsgFlag);
				#endif
				if(tempoutparameterset->DisDataPresent)
				{
					tempApp_UnionStruct->sendDisData();
				}

				if(tempuserinterfacereqdata->sendMsgFlag)
				{
					tempApp_UnionStruct->senduserinterfacerequestdata(step);
					
				}
	            
				tempuserinterfacereqdata->sendMsgFlag = 0;
			
                #ifdef EMVB_DEBUG
	            emvb_printf("\r\ntempuserinterfacereqdata->sendMsgFlagfffff\r\n = %d\r\n",tempuserinterfacereqdata->sendMsgFlag);
				#endif
				if(tempoutparameterset->DataRecordPresent)
				{
					tempApp_UnionStruct->sendendapplicationdatarecord();
				}
				#ifdef EMVB_DEBUG
	            emvb_printf("\r\ntempuserinterfacereqdata->sendMsgFlageeee\r\n = %d\r\n",tempuserinterfacereqdata->sendMsgFlag);
				#endif
				tempoutparameterset->opssendflag = 0;
				tempoutparameterset->DisDataPresent = 0;
				tempoutparameterset->DataRecordPresent = 0;
			}
			
			#ifdef EMVB_DEBUG
            emvb_printf("\r\ntempuserinterfacereqdata->sendMsgFlag1\r\n = %d\r\n",tempuserinterfacereqdata->sendMsgFlag);
			#endif
            
			
			
			

			
		}
	}
	
}


/*******************************************************************
×÷	  Õß: sxl
º¯ÊýÃû³Æ:
º¯Êý¹¦ÄÜ: ×´Ì¬Âë´íÎóÊ±ÖÃÎ»
Èë¿Ú²ÎÊý: SWA  SWB
·µ »Ø Öµ:
Ïà¹Øµ÷ÓÃ:
±¸	  ×¢:
ÐÞ¸ÄÐÅÏ¢:		20140222
********************************************************************/
void Paypassb_SetErrPar(EMVBAppUnionStruct *tempApp_UnionStruct,unsigned int step)
{
    
	OUTPARAMETERSET *tempoutparameterset;
	ERRORID *temperrid;
	USERINTERFACEREQDATA *tempuserinterfacereqdata;
	PHONEMESSAGETABLEINFO *tempphonemsgtbl;
    EMVBERRORID *tempEmvErrID;
	unsigned char temp[10];

	USERINTERFACEREQDATA tmpuserinterfacereqdata;
    
	tempoutparameterset = tempApp_UnionStruct->pOutParameterSet;
	temperrid = tempApp_UnionStruct->pErrorID;
	tempuserinterfacereqdata = tempApp_UnionStruct->pUserInterfaceReqData;
    tempphonemsgtbl = tempApp_UnionStruct->pphonemsgtable;
    tempEmvErrID = tempApp_UnionStruct->EmvErrID;
    
	
	gEmvballocator.EMVBallocator_memset(temp,0,sizeof(temp));
    #ifdef EMVB_DEBUG
    emvb_printf("\r\nseterr step = %d\r\n",step);
	#endif
	
	if(step == PAYPASSSTEP_S13_44_0)
	{
		tempuserinterfacereqdata->MessageID = tempphonemsgtbl->phonemessagetable[tempApp_UnionStruct->EMVTradeParam->PaypassSelectedPOSCIIID].MESSAGE;
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,"\x00\x00\x00",3);
		tempuserinterfacereqdata->Status = tempphonemsgtbl->phonemessagetable[tempApp_UnionStruct->EMVTradeParam->PaypassSelectedPOSCIIID].STATUS;
		tempuserinterfacereqdata->sendMsgFlag = 1;
	}
	else if(step == PAYPASSSTEP_S13_12_1)
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_CLEARDISP;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_CARDREADSUCCESS;
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,"\x00\x00\x00",3);
		tempuserinterfacereqdata->sendMsgFlag = 1;
	}
	else if(step == PAYPASSSTEP_S15_12)  //tmp user interface data
	{
		gEmvballocator.EMVBallocator_memcpy(&tmpuserinterfacereqdata,tempuserinterfacereqdata,sizeof(USERINTERFACEREQDATA));
		gEmvballocator.EMVBallocator_memset(tempuserinterfacereqdata,0,sizeof(USERINTERFACEREQDATA));
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_CLEARDISP;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_CARDREADSUCCESS;
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,"\x00\x00\x00",3);
		tempuserinterfacereqdata->sendMsgFlag = 1;
	}
	else if(step == PAYPASSSTEP_S11_E113_0)  //message hold time
	{
		tempuserinterfacereqdata->MessageID = tempphonemsgtbl->phonemessagetable[tempApp_UnionStruct->EMVTradeParam->PaypassSelectedPOSCIIID].MESSAGE;
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,PAYPASS_USERREQDATA_MSGHOLDTIME_DEFAULT,3); //HoldTimeµÄÖµ²»±ä
		tempuserinterfacereqdata->Status = tempphonemsgtbl->phonemessagetable[tempApp_UnionStruct->EMVTradeParam->PaypassSelectedPOSCIIID].STATUS;
	}
    else if(step == PAYPASSSTEP_S11_E119_0)
    {
        //tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_CARDREADSUCCESS;
    	tempuserinterfacereqdata->sendMsgFlag = 1;
    }
	else if(step == PAYPASSSTEP_S15_10)
	{
	    //tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_CLEARDISP;
		//gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,"\x00\x00\x00",3);
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_CARDREADSUCCESS;
    	tempuserinterfacereqdata->sendMsgFlag = 1;
	}
    else if(step == PAYPASSSTEP_S11_E115_9)
    {
    	tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_CLEARDISP;
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,"\x00\x00\x00",3);
    }
    else if(step == PAYPASSSTEP_S11_E115_8)
    {
    	tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_INSERTCARD;
    }
	else if(step == PAYPASSSTEP_S11_E115_7)
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_DECLINED;
	}
    else if(step == PAYPASSSTEP_S11_E115_6)
    {
    	gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,"\x00\x00\x00",3);
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_AUTHORISINGPLS;
    }
	else if(step == PAYPASSSTEP_S11_E115_5)
	{
		if(tempoutparameterset->CVM == PAYPASS_OPS_CVM_OBTAINSIGNATURE)
		{
		    tempApp_UnionStruct->EMVTradeParam->bPrintReceipt = 1;
			tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_APPROVEDSIGN;
		}
		else
		{
			tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_APPROVED;
		}
	}
    else if(step == PAYPASSSTEP_S11_E115_4)
    {
        dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AppCurcyCode,temp,0,2);
    	gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->CurrencyCode,temp,2);
    }
    else if(step == PAYPASSSTEP_S11_E115_3)
    {
        dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_BalanceAfterGAC,temp,0,6);
    	tempuserinterfacereqdata->ValueQualifier = PAYPASS_USERREQDATA_VQ_BALANCE;
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->value,temp,6);
    }
	else if(step == PAYPASSSTEP_S11_E115_2)
	{
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,PAYPASS_USERREQDATA_MSGHOLDTIME_DEFAULT,3);
	}
    else if(step == PAYPASSSTEP_S11_E115_1)
    {
        tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_NOTREADY;
    	
    }
	//else if(step == PAYPASSSTEP_S11_E112_0)
	//{
		//tempuserinterfacereqdata->MessageID = tempphonemsgtbl->phonemessagetable[tempApp_UnionStruct->EMVTradeParam->PaypassSelectedPOSCIIID].MESSAGE;
		//gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,PAYPASS_USERREQDATA_MSGHOLDTIME_DEFAULT,3);
		//tempuserinterfacereqdata->Status = tempphonemsgtbl->phonemessagetable[tempApp_UnionStruct->EMVTradeParam->PaypassSelectedPOSCIIID].STATUS;
        
		
	//}
    else if(step == PAYPASSSTEP_S53_13)
    {
    	temperrid->L2 = PAYPASS_ERRID_L2_EMPTYCANLIST;
    }
    else if(step == PAYPASSSTEP_S52_11)
    {
    	temperrid->L2 = PAYPASS_ERRID_L2_PARSINGERROR;
    }
	else if(step == PAYPASSSTEP_S52_14)
	{
		temperrid->L2 = PAYPASS_ERRID_L2_EMPTYCANLIST;
	}
	else if(step == PAYPASSSTEP_S53_7)
	{
		tempoutparameterset->status = PAYPASS_OPS_STATUS_APPROVED;
	}
	else if(step == PAYPASSSTEP_S1_7_0)
	{
		temperrid->L2 = PAYPASS_ERRID_L2_PARSINGERROR;
	}
	else if(step == PAYPASSSTEP_S1_7_1)
	{
		temperrid->L2 = PAYPASS_ERRID_L2_CARDDATAMISSING;
	}
	else if(step == PAYPASSSTEP_S3_4_0)
	{
		temperrid->L1 = 1;  //L1 error
	}
	else if(step == PAYPASSSTEP_S3_9_1)
	{
		temperrid->L2 = PAYPASS_ERRID_L2_STATUSBYTES;
		temperrid->SW12[0] = tempEmvErrID->SW12[0];
		temperrid->SW12[1] = tempEmvErrID->SW12[1];
	}
	else if(step == PAYPASSSTEP_S9_E17_0)
	{
		temperrid->L2 = PAYPASS_ERRID_L2_STATUSBYTES;
		temperrid->SW12[0] = tempEmvErrID->SW12[0];
		temperrid->SW12[1] = tempEmvErrID->SW12[1];
	}
	else if(step == PAYPASSSTEP_SR1_5_1)
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_TRYAGAIN;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_READYTOREAD;
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,"\x00\x00\x00",3);
	}
	else if(step == PAYPASSSTEP_S5_5||step == PAYPASSSTEP_S12_5)
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_TRYAGAIN;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_READYTOREAD;
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,"\x00\x00\x00",3);
	}
	else if(step == PAYPASSSTEP_SR1_12)
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_NOTREADY;
		
	}
	else if(step == PAYPASSSTEP_SR1_16)  // ||step == PAYPASSSTEP_S6_20_1
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_NOTREADY;
	}
	else if (step == PAYPASSSTEP_SR1_20)
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_NOTREADY;

		
	}
	else if(step == PAYPASSSTEP_S3_12_0)
	{
		temperrid->L2 = PAYPASS_ERRID_L2_PARSINGERROR;
	}
	else if(step == PAYPASSSTEP_S3_14_0)
	{
		temperrid->L2 = PAYPASS_ERRID_L2_CARDDATAMISSING;
	}
	else if(step == PAYPASSSTEP_S3_E41_0)
	{
		temperrid->L2 = PAYPASS_ERRID_L2_CARDDATAERR;
	}
	else if(step == PAYPASSSTEP_S3_18)
	{
		temperrid->L2 = PAYPASS_ERRID_L2_MAGNOTSUP;
	}
	else if(step == PAYPASSSTEP_S4_E4_0)
	{
		temperrid->L1 = 1;  //L1 error
	}
	else if(step == PAYPASSSTEP_S16_E1_0)
	{
		temperrid->L1 = 1;  //L1 error
	}
	else if(step == PAYPASSSTEP_S3_90_1)
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_NOTREADY;
		
	}
	else if(step == PAYPASSSTEP_S13_32_0)
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_NOTREADY;
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,PAYPASS_USERREQDATA_MSGHOLDTIME_DEFAULT,3);
		
	}
	else if(step == PAYPASSSTEP_S4_E5_0)
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_TRYAGAIN;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_READYTOREAD;
		//tempuserinterfacereqdata->sendMsgFlag = 1;
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,"\x00\x00\x00",3);
	}
	else if(step == PAYPASSSTEP_S16_E2_0)
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_TRYAGAIN;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_READYTOREAD;
		//tempuserinterfacereqdata->sendMsgFlag = 1;
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,"\x00\x00\x00",3);
	}
	else if(step == PAYPASSSTEP_S4_E10_1)
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_NOTREADY;
		
	}
	else if(step == PAYPASSSTEP_S4_E27_1)
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_NOTREADY;
		
	}
	else if(step == PAYPASSSTEP_S5_E17_1)
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_NOTREADY;
		
	}
	else if(step == PAYPASSSTEP_S5_E27_1)
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_NOTREADY;
		
	}
	else if(step == PAYPASSSTEP_S5_E31_0)
	{
	    //tempoutparameterset->CVM = PAYPASS_OPS_CVM_OBTAINSIGNATURE;
		tempoutparameterset->ReceiptinoutParameter = 1;
	}
	else if(step == PAYPASSSTEP_CVM_E18_0)
	{
	    tempApp_UnionStruct->EMVTradeParam->bPrintReceipt = 1;
	    tempoutparameterset->CVM = PAYPASS_OPS_CVM_OBTAINSIGNATURE;
		tempoutparameterset->ReceiptinoutParameter = 1;
	}
	else if(step == PAYPASSSTEP_CVM_E18_1)
	{
		tempoutparameterset->CVM = PAYPASS_OPS_CVM_ONLINEPIN;
	}
	else if(step == PAYPASSSTEP_CVM_E8_0)
	{
		tempoutparameterset->CVM = PAYPASS_OPS_CVM_NOCVMREQ;
	}
	else if(step == PAYPASSSTEP_CVM_E4_0)
	{
		tempoutparameterset->CVM = PAYPASS_OPS_CVM_CONFVERIFIED;
	}
	else if(step == PAYPASSSTEP_GAC_6)
	{
		temperrid->L2 = PAYPASS_ERRID_L2_IDSDATAERR;
	}
	else if(step == PAYPASSSTEP_GAC_11)
	{
		temperrid->L2 = PAYPASS_ERRID_L2_IDSNOMATCHAC;
	}
	else if(step == PAYPASSSTEP_GAC_12)
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_NOTREADY;
	}
	else if(step == PAYPASSSTEP_S78_20_0)
	{
		tempoutparameterset->CVM = PAYPASS_OPS_CVM_CONFVERIFIED;
	}
	else if(step == PAYPASSSTEP_S13_4_0)
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_TRYAGAIN;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_READYTOREAD;
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,"\x00\x00\x00",3);
	}
	else if(step == PAYPASSSTEP_S13_10_0)
	{
		temperrid->L2 = PAYPASS_ERRID_L2_STATUSBYTES;
		temperrid->SW12[0] = tempEmvErrID->SW12[0];
		temperrid->SW12[1] = tempEmvErrID->SW12[1];
	}
	else if(step == PAYPASSSTEP_S13_13_0)
	{
		temperrid->L2 = PAYPASS_ERRID_L2_PARSINGERROR;
	}
	else if(step == PAYPASSSTEP_S13_14_4)
	{
		temperrid->L2 = PAYPASS_ERRID_L2_CARDDATAMISSING;
	}
	else if(step == PAYPASSSTEP_S14_21_1)
	{
		temperrid->L2 = PAYPASS_ERRID_L2_CARDDATAERR;
	}
	else if(step == PAYPASSSTEP_S13_42_0)
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_DECLINED;
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,PAYPASS_USERREQDATA_MSGHOLDTIME_DEFAULT,3);
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_NOTREADY;
		
	}
	else if(step == PAYPASSSTEP_S13_23_0)
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_CLEARDISP;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_CARDREADSUCCESS;
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,"\x00\x00\x00",3);
	}
	else if(step == PAYPASSSTEP_S9_E27_0)
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_CLEARDISP;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_CARDREADSUCCESS;
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,"\x00\x00\x00",3);
		tempuserinterfacereqdata->sendMsgFlag = 1;
	}
	else if(step == PAYPASSSTEP_S10_E5_0)
	{
	    
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_TRYAGAIN;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_READYTOREAD;
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,"\x00\x00\x00",3);
		
	}
	else if(step == PAYPASSSTEP_S10_E14_0)
	{
		temperrid->L2 = PAYPASS_ERRID_L2_PARSINGERROR;
	}
	else if(step == PAYPASSSTEP_S10_E16_0)
	{
		temperrid->L2 = PAYPASS_ERRID_L2_CARDDATAMISSING;
	}
	else if(step == PAYPASSSTEP_S10_E18_0)
	{
		temperrid->L2 = PAYPASS_ERRID_L2_CARDDATAERR;
	}
	else if(step == PAYPASSSTEP_S10_E50_0)
	{   
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_NOTREADY;
		 gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,PAYPASS_USERREQDATA_MSGHOLDTIME_DEFAULT,3);
	}
	else if(step == PAYPASSSTEP_S9_E9_0)
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_TRYAGAIN;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_READYTOREAD;
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,"\x00\x00\x00",3);
	}
	else if(step == PAYPASSSTEP_S9_7)
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_NOTREADY;
	}
	else if(step == PAYPASSSTEP_S9_E14_0)
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_TRYAGAIN;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_READYTOREAD;
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,"\x00\x00\x00",3);
	}
	else if(step == PAYPASSSTEP_S10_E19_0)
	{
		temperrid->L2 = PAYPASS_ERRID_L2_IDSWRITEERR;
	}
	else if(step == PAYPASSSTEP_S10_E20_0)
	{
		temperrid->L2 = PAYPASS_ERRID_L2_PARSINGERROR;
	}
	else if(step == PAYPASSSTEP_S10_E22_0)
	{
		temperrid->L2 = PAYPASS_ERRID_L2_CARDDATAMISSING;
	}
	else if(step == PAYPASSSTEP_S10_11)
	{
		temperrid->L2 = PAYPASS_ERRID_L2_IDSREADERR;
	}
	else if(step == PAYPASSSTEP_S10_E24_0)
	{
		temperrid->L2 = PAYPASS_ERRID_L2_CARDDATAERR;
	}
	else if(step == PAYPASSSTEP_S11_E46_0)
	{
		temperrid->L2 = PAYPASS_ERRID_L2_CAMFAILED;
	}
	else if(step == PAYPASSSTEP_S11_E90_0)
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_NOTREADY;
        gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,PAYPASS_USERREQDATA_MSGHOLDTIME_DEFAULT,3);
		
	}
	else if(step == PAYPASSSTEP_S51_11_0)
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,PAYPASS_USERREQDATA_MSGHOLDTIME_DEFAULT,3);
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_NOTREADY;
		
	}
	else if(step == PAYPASSSTEP_S52_7)
	{
		temperrid->L2 = PAYPASS_ERRID_L2_STATUSBYTES;
		temperrid->SW12[0] = tempEmvErrID->SW12[0];
		temperrid->SW12[1] = tempEmvErrID->SW12[1];
        
		
	}
	else if(step == PAYPASSSTEP_S52_18)  //?20150612ÒªÏÔÊ¾8¸ö×Ö½Ú5F2D
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		//gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,PAYPASS_USERREQDATA_MSGHOLDTIME_DEFAULT,3);
		//#ifdef PAYPASSV303
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_NOTREADY;
        //#else
        //tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_IDLE;
		//#endif
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,PAYPASS_USERREQDATA_MSGHOLDTIME_DEFAULT,3);
        
		
	}
	else if(step == PAYPASSSTEP_S53_14)
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		//#ifdef PAYPASSV303
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_NOTREADY;
        //#else
        //tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_IDLE;
		//#endif
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,PAYPASS_USERREQDATA_MSGHOLDTIME_DEFAULT,3);
	}
	else if(step == PAYPASSSTEP_S52_8)
	{
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,PAYPASS_USERREQDATA_MSGHOLDTIME_DEFAULT,3);
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_NOTREADY;
		
	}
	else
	{
	    
		tempuserinterfacereqdata->MessageID = PAYPASS_USERREQDATA_MSGID_ERROR_OTHERCARD;
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata->HoldTime,PAYPASS_USERREQDATA_MSGHOLDTIME_DEFAULT,3);
		tempuserinterfacereqdata->Status = PAYPASS_USERREQDATA_STATUS_IDLE;
		tempuserinterfacereqdata->sendMsgFlag = 1;
		
	}
    
    
    
	if(tempuserinterfacereqdata->sendMsgFlag)
	{
		tempApp_UnionStruct->senduserinterfacerequestdata(step);  
		tempuserinterfacereqdata->sendMsgFlag = 0;
	}
    
	if(step == PAYPASSSTEP_S15_12)
	{
		gEmvballocator.EMVBallocator_memcpy(tempuserinterfacereqdata,&tmpuserinterfacereqdata,sizeof(USERINTERFACEREQDATA));
	}
	
}


//20130731  20140222
unsigned char  Paypassb_MatchMasterAID(unsigned char *aid,unsigned char aidlen)
{
	if(aidlen < 5)
	{
		return 0;
	}
    
	if((gEmvballocator.EMVBallocator_memcmp(aid,"\xA0\x00\x00\x00\x04",5) == 0)||(gEmvballocator.EMVBallocator_memcmp(aid,"\xB0\x12\x34\x56\x78",5) == 0))
	{
	    #ifdef EMVB_DEBUG
        emvb_printf("\r\nmatch master AID\r\n");
		#endif
		return 1;
	}
	else
	{
		return 0;
	}
	
}

/*******************************************************************
×÷    Õß:
º¯ÊýÃû³Æ: int Emv_MatchTermAID(unsigned char* aid,unsigned char aidLen,TERMAPP *Applist,unsigned char listnum)
º¯Êý¹¦ÄÜ: ÖÕ¶ËÁÐ±íÆ¥Åä
Èë¿Ú²ÎÊý: aid - ÐèÒªÆ¥ÅäµÄÓ¦ÓÃÃû³Æ
          aidLen -  ÐèÒªÆ¥ÅäµÄÓ¦ÓÃµÄ³¤¶È
          Applist -   ÖÕ¶ËÓ¦ÓÃÁÐ±í
          listnum -ÖÕ¶ËÓ¦ÓÃÁÐ±íÊýÁ¿
·µ »Ø Öµ: i != -1¶ÔÓ¦µÄÖÕ¶ËÁÐ±íÖÐµÄÓ¦ÓÃµÄÓ¦ÓÃºÅ
          -1   Æ¥ÅäÊ§°Ü
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:  sxl0215
********************************************************************/
/*
int Paypassb_MatchTermAID(unsigned char KernelID,unsigned char* aid,unsigned char aidLen,TERMAPP *Applist,unsigned char listnum)
{
	int i,j;

	#ifdef SXL_DEBUG
    emvb_printf("\r\nEmv_MatchTermAID listnum = %d",listnum);
	#endif
	
	for(i=0;i<listnum;i++)
	{
	    #ifdef SXL_DEBUG
        emvb_printf("\r\n Emv_MatchTermAID i = %d %d %d\r\n ",i,aidLen,(Applist+i)->AIDLen);
		for(j = 0;j<aidLen;j++)
		{
			emvb_printf("%02x ",aid[j]);
		}
		emvb_printf("\r\n");
		for(j = 0;j<(Applist+i)->AIDLen;j++)
		{
			emvb_printf("%02x ",Applist[i].AID[j]);
		}
		emvb_printf("\r\n");


		emvb_printf("\r\nKernelID %d %d\r\n",KernelID,(Applist+i)->KernelID);
		#endif
        if(KernelID != (Applist+i)->KernelID)
        {
        	continue;
        }
		
		//ÏÂÔØÊ±ºÍ¶¨ÒåµÄÏà·´20110426
		//if((Applist+i)->ASI!=PARTIAL_MATCH)	//²¿·ÖÆ¥Åä
		//{
			if((!gEmvballocator.EMVBallocator_memcmp(aid,(Applist+i)->AID,(Applist+i)->AIDLen))&&(KernelID == (Applist+i)->KernelID))
				return i;
		//}
		//else//exact match
		//{
			//if((!gEmvballocator.EMVBallocator_memcmp(aid,(Applist+i)->AID,aidLen))&&(KernelID == (Applist+i)->KernelID))	//ÍêÈ«Æ¥Åä
			//	return i;
		//}
	}
	return -1;
}
*/
/*******************************************************************
×÷    Õß: sxl
º¯Êý¹¦ÄÜ: ½âÎöSELECTÃüÁî·µ»ØµÄ¿¨Êý¾Ý
Èë¿Ú²ÎÊý: selectRet - ¿¨ÎÄ¼þÑ¡ÔñÓ¦´ð½á¹¹Ìå
          DataOut -  ¿¨·µ»ØµÄÊý¾Ý
          LenOut -   ¿¨·µ»ØµÄÊý¾Ý³¤¶È
·µ »Ø Öµ: EMV_OK£¨0£©-³É¹¦
          ERR_EMV_IccDataFormat£¨34£© - IC¿¨Êý¾Ý¸ñÊ½´í
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:       20140222
********************************************************************/
unsigned char Paypassb_ReadSelectRetData(SELECT_RET* selectRet,unsigned char* DataOut,unsigned short LenOut,EMVBAppUnionStruct *tempAppUnionStruct)
{
    int matchnum;
	LISTAPPDATA *tempAppAppData;
	unsigned char *tempappnum;
	unsigned char j,k;  //i,
	unsigned short index,indexFCI,indexFCIProp,len,lenFCI,lenFCIProp;
	int indexIssuerDiscret,lenIssuerDiscret;
	int indexAppApp,lenAppApp;
	unsigned char priorityexist;
	unsigned short templen;
    unsigned char ifneedcompare;
	TERMAPP tempAppTermApp;
    
	tempappnum = &(tempAppUnionStruct->EMVTradeParam->AppListCandidatenum);
	tempAppAppData = tempAppUnionStruct->EMVTradeParam->AppListCandidate;
	*tempappnum = 0;
    
	
	index=0;
	if(DataOut[index]!=0x6F)	//FCIÄ£°å±êÊ¶
	{ 
		return ERR_EMV_IccDataFormat; //FCI template
	}
	index++;
    
    if(ParseExtLen(DataOut,&index,&lenFCI))
    {
    	return ERR_EMV_IccDataFormat;
    }
	indexFCI=index;
	
	while(index<indexFCI+lenFCI)
	{
		if(index>=LenOut) return ERR_EMV_IccDataFormat;
		if(DataOut[index]==0xFF || DataOut[index]==0x00) { index++; continue;}
		else if(DataOut[index]==0x84)	//DFÃû
		{
			if(selectRet->DFNameExist==1) return ERR_EMV_IccDataFormat;
			index++;
			if(ParseExtLen(DataOut,&index,&len))
			{
				return ERR_EMV_IccDataFormat;
			}
			selectRet->DFNameLen=len;
			if(selectRet->DFNameLen>16) return ERR_EMV_IccDataFormat;
			gEmvballocator.EMVBallocator_memcpy(selectRet->DFName,DataOut+index,len);
			index+=len;
			selectRet->DFNameExist=1;
			
			
		}
		else if(DataOut[index]==0xA5)	//FCIÊý¾Ý×¨ÓÃÄ£°å
		{
			selectRet->FCIPropExist=1;
			index++;

            if(ParseExtLen(DataOut,&index,&lenFCIProp))
            {
            	return ERR_EMV_IccDataFormat;
            }
			indexFCIProp=index;

			
			while(index<indexFCIProp+lenFCIProp)
			{
				if(index>=LenOut) return ERR_EMV_IccDataFormat;
				if(DataOut[index]==0xFF || DataOut[index]==0x00) { index++; continue;}
				else if(!gEmvballocator.EMVBallocator_memcmp(DataOut+index,"\xBF\x0C",2)) //FCI ·¢¿¨·½×Ô¶¨ÒåÊý¾Ý
				{
					if(selectRet->IssuerDiscretExist==1) return ERR_EMV_IccDataFormat;
					index+=2;
					if(ParseExtLen(DataOut,&index,&len))
					{
						return ERR_EMV_IccDataFormat;
					}
					if(len >253) return ERR_EMV_IccDataFormat;
					selectRet->IssuerDiscretLen=len;   //sxl 090211
					//memcpy(selectRet->IssuerDiscret,DataOut+index,len);
					selectRet->IssuerDiscretExist=1;

					indexIssuerDiscret=index;
					lenIssuerDiscret=len;
					while(index<indexIssuerDiscret+lenIssuerDiscret)
					{
						if(index>=LenOut) return ERR_EMV_IccDataFormat;
						if(DataOut[index]==0xFF || DataOut[index]==0x00) { index++; continue;}
						else if(DataOut[index] == 0x61)
						{
						    selectRet->paypassselectppse61tagexist = 1;
							gEmvballocator.EMVBallocator_memset(tempAppAppData+(*tempappnum),0,sizeof(LISTAPPDATA)); //ÇåÓ¦ÓÃ
							priorityexist = 0;
							index+=1;
							if(ParseExtLen(DataOut,&index,&len))
							{
								return ERR_EMV_IccDataFormat;
							}
							indexAppApp=index;
							lenAppApp=len;
							while(index<indexAppApp+lenAppApp)
							{
								if(index>=LenOut) return ERR_EMV_IccDataFormat;
								if(DataOut[index]==0xFF || DataOut[index]==0x00) { index++; continue;}
								else if(DataOut[index] == 0x4F) //AID //Á½¸ö×Ö½ÚµÄ³¤¶È
								{
									index+=1;

									if(ParseExtLen(DataOut,&index,&templen))
									{
										return ERR_EMV_IccDataFormat;
									}
									
									(tempAppAppData + (*tempappnum))->AIDLen = templen;
									if((tempAppAppData + (*tempappnum))->AIDLen > 16) (tempAppAppData + (*tempappnum))->AIDLen = 16;
									//index++;
									j = (tempAppAppData + (*tempappnum))->AIDLen;
									gEmvballocator.EMVBallocator_memcpy((tempAppAppData + (*tempappnum))->AID,DataOut+index,j);
									index+=j;
								}
								else if(DataOut[index] == 0x50) //AppLabel
								{
									index+=1;

									if(ParseExtLen(DataOut,&index,&templen))
									{
										return ERR_EMV_IccDataFormat;
									}
									
									(tempAppAppData + (*tempappnum))->AppLabelLen = templen;
									if((tempAppAppData + (*tempappnum))->AppLabelLen > 16) (tempAppAppData + (*tempappnum))->AppLabelLen = 16;
									//index++;
									j = (tempAppAppData + (*tempappnum))->AppLabelLen;
									gEmvballocator.EMVBallocator_memcpy((tempAppAppData + (*tempappnum))->AppLabel,DataOut+index,j);
									index+=j;
								}
								else if(DataOut[index] == 0x87) //AppPriority
								{
									index+=1;
									if(ParseExtLen(DataOut,&index,&templen))
									{
										return ERR_EMV_IccDataFormat;
									}
									if(templen !=1)
									{
										return ERR_EMV_IccDataFormat;
									}
									(tempAppAppData + (*tempappnum))->Priority = DataOut[index];
									index++;
									priorityexist = 1;
								}
								else if(!gEmvballocator.EMVBallocator_memcmp(DataOut+index,"\x9F\x2A",2))  //Kernel Identifier  jiguang add for Paypass ver 3.0.1  20121217
								{  //²»ÖªµÀkernel ID ºóÃæ»¹ÓÐÊ²Ã´ÓÃ´¦£¬ÔÚÑ¡Ó¦ÓÃµÄÊ±ºòÖ»ÄÜÇëÇó
									//Requested Kernel ID ÊÇ '02'		jiguang ?
									index+=2;
									if(ParseExtLen(DataOut,&index,&templen))
									{
										return ERR_EMV_IccDataFormat;
									}
									
									//j = DataOut[index];
									(tempAppAppData + (*tempappnum))->KernelIdentifierLen  = templen;
									#ifdef PAYPASSV303
									if((tempAppAppData + (*tempappnum))->KernelIdentifierLen == 2) //20150612
									{
										return ERR_EMV_IccDataFormat;
									}
									#endif
									//index++;
									if((tempAppAppData + (*tempappnum))->KernelIdentifierLen > 10)  //?20150612
									{
										(tempAppAppData + (*tempappnum))->KernelIdentifierLen = 10;
									}
									gEmvballocator.EMVBallocator_memcpy((tempAppAppData + (*tempappnum))->KernelIdentifier,DataOut+index,(tempAppAppData + (*tempappnum))->KernelIdentifierLen);
									index+=templen;
								}
								/*
								else if(DataOut[index] == 0x61)
								{
									break;
								}
								*/
								else
								{
									k=DataOut[index];
									if((k&0x1F)==0x1F)
										index++;
									index++;
									if(ParseExtLen(DataOut,&index,&len))
									{
										return ERR_EMV_IccDataFormat;
									}
									index+=len;
								}
							}
							if((tempAppAppData + (*tempappnum))->AIDLen != 0)//È·±£Ã¿¸öÄ¿Â¼Èë¿Ú¶¼ÓÐAID
							{
								//for(i=0;i<temptermcapknum;i++)  
								//{
									/*if( (!gEmvballocator.EMVBallocator_memcmp((tempAppAppData + (*tempappnum))->AID,(temptermcapk+i)->RID,5)))
									{
										(*tempappnum)++; //huxiang add 091013
									}*/
								// 2010/10/19
								if(priorityexist == 0)
								{
									(tempAppAppData + (*tempappnum))->Priority = 0;
								}
								ifneedcompare = 0;

								//KID not exist
                                if((tempAppAppData + (*tempappnum))->KernelIdentifierLen == 0)
                                {
                                	ifneedcompare = Paypassb_MatchMasterAID((tempAppAppData + (*tempappnum))->AID,(tempAppAppData + (*tempappnum))->AIDLen);
									#ifdef EMVB_DEBUG
                                    emvb_printf("\r\nifneedcompare = %d\r\n",ifneedcompare);
									#endif
                                }
								else
								{
									if((tempAppAppData + (*tempappnum))->KernelIdentifier[0] == 0x02||
										(tempAppAppData + (*tempappnum))->KernelIdentifier[0] == 0x42)
									{
										ifneedcompare = 1;
									}
									else
									{
										if((tempAppAppData + (*tempappnum))->KernelIdentifier[0] == 0x00||
										(tempAppAppData + (*tempappnum))->KernelIdentifier[0] == 0x40)
										{
											ifneedcompare = Paypassb_MatchMasterAID((tempAppAppData + (*tempappnum))->AID,(tempAppAppData + (*tempappnum))->AIDLen);
										}
									}
								}

								if(ifneedcompare)
								{
									(tempAppAppData + (*tempappnum))->ReqKernelID = 0x02;
								}

								
								    
								matchnum= tempAppUnionStruct->check_MatchTermAID((tempAppAppData + (*tempappnum))->ReqKernelID,(tempAppAppData + (*tempappnum))->AID,(tempAppAppData + (*tempappnum))->AIDLen,&tempAppTermApp,ICC_KERNEL_ID_2_PAYPASS);
								if(matchnum>=0)
								{
								    (tempAppAppData + (*tempappnum))->AidInTermLen = tempAppTermApp.AIDLen;
					                		gEmvballocator.EMVBallocator_memcpy((tempAppAppData + (*tempappnum))->AidInTerm,tempAppTermApp.AID,(tempAppAppData + (*tempappnum))->AidInTermLen);
									(*tempappnum)++;
								}
									
							}
						}
						else if(!gEmvballocator.EMVBallocator_memcmp(DataOut+index,"\x9F\x4D",2))//Log EntryÈÕÖ¾Èë¿Ú
						{
							if(selectRet->LogEntryExist==1) return ERR_EMV_IccDataFormat;
							index+=2;
							if(ParseExtLen(DataOut,&index,&len))
							{
								return ERR_EMV_IccDataFormat;
							}
							selectRet->LogEntryLen=len;
							//gEmvballocator.EMVBallocator_memcpy(selectRet->LogEntry,DataOut+index,selectRet->LogEntryLen);
							index+=selectRet->LogEntryLen;
							selectRet->LogEntryExist=1;
						}
						else
						{
							k=DataOut[index];
							if((k&0x1F)==0x1F)
								index++;
							index++;
							if(ParseExtLen(DataOut,&index,&len))
							{
								return ERR_EMV_IccDataFormat;
							}
							index+=len;
						}

					}
				}
				else//other unknown TLV data
				{
					k=DataOut[index];
					if((k&0x1F)==0x1F)
						index++;
					index++;
					if(ParseExtLen(DataOut,&index,&len))
					{
						return ERR_EMV_IccDataFormat;
					}
					index+=len;
				}
			}
			if(index!=indexFCIProp+lenFCIProp)
				return ERR_EMV_IccDataFormat;
		}
		else
		{
			k=DataOut[index];
			if((k&0x1F)==0x1F)
				index++;
			index++;
			if(ParseExtLen(DataOut,&index,&len))
			{
				return ERR_EMV_IccDataFormat;
			}
			index+=len;
		}

	}
	if(index!=indexFCI+lenFCI)
		return ERR_EMV_IccDataFormat;
	
	return EMV_OK;

}


/*******************************************************************
×÷    Õß: sxl
º¯ÊýÃû³Æ: unsigned char Paywave_SelectDFRetData(unsigned char indexDF,SELECT_RET* selectRet,APDU_RESP *apdu_r,AppUnionStruct *tempAppUnionStruct)
º¯Êý¹¦ÄÜ: ½âÎöSELECTÃüÁî·µ»ØµÄ¿¨Êý¾Ý
Èë¿Ú²ÎÊý: indexDF - DFË÷Òý
          SELECT_RET -  Ñ¡ÔñÎÄ¼þ½á¹¹Ìå
          apdu_r -   ¿¨·µ»ØµÄÊý¾Ý
·µ »Ø Öµ: EMV_OK£¨0£©-³É¹¦
          ERR_EMV_IccDataFormat£¨34£© - IC¿¨Êý¾Ý¸ñÊ½´í
          ERR_EMV_IccReturn -ÆäËû´íÎó·µ»Ø
          ERR_BLOCKORFORMATERR -Ëø¿¨
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:        20140222
********************************************************************/
unsigned char Paypassb_SelectDFRetData(APDU_RESP *apdu_r,EMVBAppUnionStruct *tempAppUnionStruct)
{
	SELECT_RET selectRet;


	if(apdu_r->SWA==0x90 && apdu_r->SWB==0x00)
	{

		gEmvballocator.EMVBallocator_memset((unsigned char*)&selectRet,0,sizeof(SELECT_RET));
		if(Paypassb_ReadSelectRetData(&selectRet,apdu_r->DataOut,apdu_r->LenOut,tempAppUnionStruct)!=EMV_OK) 
		{
			return ERR_EMV_IccDataFormat;
		}
		if(selectRet.DFNameExist==0 || selectRet.FCIPropExist==0 ||selectRet.IssuerDiscretExist == 0
			||selectRet.paypassselectppse61tagexist == 0)
		{
			return ERR_EMV_IccDataFormat;
		}
		
		//Insert DF name into tree
		//dllemvb_avl_createsettagvalue((unsigned char *)TAG_DFName,selectRet.DFName,selectRet.DFNameLen);
		
		if(selectRet.SFIExist==1)
		{
			if(selectRet.SFI<1 || selectRet.SFI>10 )
			{
				return ERR_EMV_IccDataFormat;
			}
		}
		/*
		if(selectRet.LangPreferExist==1)
		{
			dllemvb_avl_createsettagvalue((unsigned char *)TAG_LangPrefer,selectRet.LangPrefer,selectRet.LangPreferLen);
		}
		if(selectRet.ICTIExist==1)
		{
			dllemvb_avl_createsettagvalue((unsigned char *)TAG_ICTI,&selectRet.ICTI,1);
		}
		*/
        
        
		return EMV_OK;


	}
	else
	{

        return PAYPASS_SW1SW2ERR;
    }
     
}


/*******************************************************************
×÷    Õß: sxl
º¯ÊýÃû³Æ: unsigned char Paywave_SelectApp(AppUnionStruct *tempApp_UnionStruct)
º¯Êý¹¦ÄÜ: paywaveÑ¡ÔñÓ¦ÓÃ
Èë¿Ú²ÎÊý: ÎÞ
·µ »Ø Öµ: ÎÞ
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:         20140222
********************************************************************/
unsigned char Paypassb_SelectApp(EMVBAppUnionStruct *tempApp_UnionStruct)
{
	
	APDU_SEND apdu_s;
    APDU_RESP apdu_r;
	unsigned char retCode;
    
    
	
	EMVB_COMMAND_SELECT((unsigned char *)"2PAY.SYS.DDF01",14,0,&apdu_s);
	
	tempApp_UnionStruct->EMVB_qPBOCIccIsoCommand(&apdu_s,&apdu_r);
    if(apdu_r.ReadCardDataOk != EMV_OK)
    {
        if(tempApp_UnionStruct->EmvErrID->L3 != EMVB_ERRID_L3_STOP)
        {
        	Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S52_5);
        }
		//sxl PPSE STOP
    	return ERR_APP_TIMEOUT;
    }
    
	
    retCode = Paypassb_SelectDFRetData(&apdu_r,tempApp_UnionStruct);
	if(retCode == PAYPASS_SW1SW2ERR)
	{
	    Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S52_7);
		Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S52_8);
		Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S52_9);
	}
	else if(retCode != EMV_OK)
	{
		Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S52_11);
		Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S52_18);
		Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S52_19);
	}
    else
    {
    	if(tempApp_UnionStruct->EMVTradeParam->AppListCandidatenum == 0)
    	{
    		Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S52_14);
			Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S52_18);
			Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S52_19);
    	}
    }
	
    return retCode;
    
				    
}


//»ñÈ¡Ó¦ÓÃÑ¡ÔñÁÐ±í
/*******************************************************************
×÷    Õß: sxl
º¯ÊýÃû³Æ: unsigned char Paywaveb_GetAppCandidate(AppUnionStruct *tempApp_UnionStruct)
º¯Êý¹¦ÄÜ: Paywave»ñÈ¡Ó¦ÓÃÁÐ±í
Èë¿Ú²ÎÊý: ÎÞ
·µ »Ø Öµ: ÎÞ
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:         20140222
********************************************************************/
unsigned char Paypassb_GetAppCandidate(EMVBAppUnionStruct *tempApp_UnionStruct)
{
	unsigned char retcode = 0;
    
	tempApp_UnionStruct->EMVTradeParam->ifcmdsaved = 0;
	retcode = Paypassb_SelectApp(tempApp_UnionStruct);      //½«ÖÕ¶ËÓ¦ÓÃÁÐ±í´«ÏÂÀ´
    if(retcode != EMV_OK)
    {
    	retcode = PAYPASS_ENDAPPLICATION;
    }
	return retcode;
	
}



/*******************************************************************
×÷    Õß: sxl
º¯ÊýÃû³Æ: unsigned char Paywave_ChooseApp(AppUnionStruct *App_UnionStruct)
º¯Êý¹¦ÄÜ: Ñ¡ÔñAPP
Èë¿Ú²ÎÊý:
·µ »Ø Öµ:
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:         20140222
********************************************************************/
unsigned char Paypassb_ChooseApp(EMVBAppUnionStruct *tempApp_UnionStruct)
{	
	unsigned char i,j,temp;  //bConfirm,bPriority,
	unsigned char *tempselectappno;
	unsigned char *tempappnum;
    
	unsigned char noprioritynum = 0;
	unsigned char tmpseq[16];
	unsigned char tmpapprtiority[16];
	unsigned char AppPriority[16];
    unsigned char AppSeq[16];
	
	
	LISTAPPDATA *tempAppAppData;
	
    tempselectappno = &(tempApp_UnionStruct->EMVTradeParam->SelectedAppNo);
	tempappnum = &(tempApp_UnionStruct->EMVTradeParam->AppListCandidatenum);
    tempAppAppData = tempApp_UnionStruct->EMVTradeParam->AppListCandidate;
	
    
    if(*tempappnum<1)      //Ã»ÓÐºÍÖÕ¶ËÁÐ±íÆ¥ÅäµÄ±êÇ©
	{
		return ERR_EMV_NoAppSel;
	}
    
	
	*tempselectappno = 0xff;
		
	
	if(*tempselectappno>*tempappnum)
	{
		//bPriority=1;
		//bConfirm=1;
		for(i=0;i<*tempappnum;i++)
		{
			AppPriority[i]=(tempAppAppData+i)->Priority & 0x0F;
			AppSeq[i]=i;
		}
		if(*tempappnum==1)
		{		
		    *tempselectappno = 0;
		}
		else
		{
			for(j=0;j<*tempappnum-1;j++)
			{
				for(i=0;i<*tempappnum-1-j;i++)
				{
					if(AppPriority[i]>AppPriority[i+1])
					{
						temp=AppPriority[i];
						AppPriority[i]=AppPriority[i+1];
						AppPriority[i+1]=temp;
						temp=AppSeq[i];
						AppSeq[i]=AppSeq[i+1];
						AppSeq[i+1]=temp;
					}
				}
			}
			noprioritynum = 0;
			for(i=0;i<*tempappnum;i++)
			{
				if(AppPriority[i]==0) noprioritynum++;
			}
			if(noprioritynum)  //have no priority app
			{
				gEmvballocator.EMVBallocator_memcpy(tmpapprtiority,&AppPriority[noprioritynum],*tempappnum - noprioritynum);
				gEmvballocator.EMVBallocator_memcpy(&tmpapprtiority[*tempappnum - noprioritynum],AppPriority,noprioritynum);
				gEmvballocator.EMVBallocator_memcpy(AppPriority,tmpapprtiority,*tempappnum);

				gEmvballocator.EMVBallocator_memcpy(tmpseq,&AppSeq[noprioritynum],*tempappnum - noprioritynum);
				gEmvballocator.EMVBallocator_memcpy(&tmpseq[*tempappnum - noprioritynum],AppSeq,noprioritynum);
				gEmvballocator.EMVBallocator_memcpy(AppSeq,tmpseq,*tempappnum);
				
			}
            
			*tempselectappno = AppSeq[0];
			
		}
	}

	if(*tempselectappno>*tempappnum)
	{
		return ERR_EMV_CancelTrans;
	}
	
	return EMV_OK;	
}


/*******************************************************************
×÷    Õß: sxl
º¯Êý¹¦ÄÜ: ½âÎöSELECTÃüÁî·µ»ØµÄ¿¨Êý¾Ý
Èë¿Ú²ÎÊý: selectRet - ¿¨ÎÄ¼þÑ¡ÔñÓ¦´ð½á¹¹Ìå
          DataOut -  ¿¨·µ»ØµÄÊý¾Ý
          LenOut -   ¿¨·µ»ØµÄÊý¾Ý³¤¶È
·µ »Ø Öµ: EMV_OK£¨0£©-³É¹¦
          ERR_EMV_IccDataFormat£¨34£© - IC¿¨Êý¾Ý¸ñÊ½´í
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:    20140222
********************************************************************/
unsigned char Paypassb_FinalReadSelectRetData(SELECT_RET* selectRet,unsigned char* DataOut,unsigned short LenOut,EMVBAppUnionStruct *tempAppUnionStruct)
{
    
	//unsigned char k;   //j,
	unsigned short index,indexFCI,indexFCIProp,lenFCI,lenFCIProp,templen;   //len,
	unsigned short indexIssuerDiscret;//,lenIssuerDiscret;
	//unsigned short indexAppApp,lenAppApp;
	unsigned char ret;
	unsigned char bIntable;
    EMVTAGCVLITEM *emvitem;
	unsigned char *temp;   //[300]
	
    if(LenOut == 0)
    {
		return EMV_OK;
    }
	
	index=0;
	if(DataOut[index]!=0x6F)	//FCIÄ£°å±êÊ¶
	{ 
		return ERR_EMV_IccDataFormat; //FCI template
	}
	index++;

    if(ParseExtLen(DataOut,&index,&lenFCI))
    {
    	return ERR_EMV_IccDataFormat;
    }
	indexFCI=index;
	
	while(index<indexFCI+lenFCI)
	{
		if(index>=LenOut) return ERR_EMV_IccDataFormat;
		if(DataOut[index]==0xFF || DataOut[index]==0x00) { index++; continue;}
		else if(DataOut[index]==0x84)	//DFÃû
		{
			if(selectRet->DFNameExist==1) return ERR_EMV_IccDataFormat;
			index++;

			if(ParseExtLen(DataOut,&index,&templen))
			{
				return ERR_EMV_IccDataFormat;
			}

			
			selectRet->DFNameLen = templen;
			if(selectRet->DFNameLen>16) return ERR_EMV_IccDataFormat;
			gEmvballocator.EMVBallocator_memcpy(selectRet->DFName,DataOut+index,templen);
			selectRet->DFNameExist=1;
			
			index+=templen;
			
			//termpcardinfo->DFNameLen = selectRet->DFNameLen;
			//gEmvballocator.EMVBallocator_memcpy(termpcardinfo->DFName,selectRet->DFName,termpcardinfo->DFNameLen);
			dllemvb_avl_createsettagvalue((unsigned char *)TAG_DFName,selectRet->DFName,selectRet->DFNameLen);
            
			
		}
		else if(DataOut[index]==0xA5)	//FCIÊý¾Ý×¨ÓÃÄ£°å
		{
			selectRet->FCIPropExist=1;
			index++;

			
            if(ParseExtLen(DataOut,&index,&lenFCIProp))
            {
            	return ERR_EMV_IccDataFormat;
            }
			indexFCIProp=index;

            while(index<indexFCIProp+lenFCIProp)
            {
	            ret = Paypassb_ParseAndStoreCardResponse(tempAppUnionStruct,DataOut,&index,&bIntable,5);
				if(ret != EMV_OK)
				{
					return ERR_EMV_IccDataFormat;
				}
            }
			if(index!=indexFCIProp+lenFCIProp)
				return ERR_EMV_IccDataFormat;
            
            //½âÎöBF0C
            indexIssuerDiscret = 0;
			emvitem = dllemvb_avl_gettagitempointer((unsigned char *)TAG_FCIDisData);
			if(emvitem != NULL)
			{
			    #ifdef EMVB_DEBUG
                emvb_printf("\r\nparse TAG_FCIDisData\r\n");
				#endif

				temp = (unsigned char *)emvblib_malloc(300);
			    gEmvballocator.EMVBallocator_memset(temp,0,300);
				gEmvballocator.EMVBallocator_memcpy(temp,emvitem->data,emvitem->len);
				while(indexIssuerDiscret < emvitem->len)
				{
					ret = Paypassb_ParseAndStoreCardResponse(tempAppUnionStruct,temp,&indexIssuerDiscret,&bIntable,6);
					if(ret != EMV_OK)
					{
					    emvblib_free(temp);
						return ERR_EMV_IccDataFormat;
					}
				}

				emvblib_free(temp);

				if(indexIssuerDiscret != emvitem->len)
				{
					return ERR_EMV_IccDataFormat;
				}

				dllemvb_avl_delete((unsigned char *)TAG_FCIDisData);
			}

			
			
		}
		else
		{
		    //
		    ret = Paypassb_ParseAndStoreCardResponse(tempAppUnionStruct,DataOut,&index,&bIntable,7);
			if(ret != EMV_OK)
			{
				return ERR_EMV_IccDataFormat;
			}
			/*
			k=DataOut[index];
			if((k&0x1F)==0x1F)
				index++;
			index++;
			if(ParseExtLen(DataOut,&index,&len))
			{
				return ERR_EMV_IccDataFormat;
			}
			index+=len;
			*/
		}

	}
	if(index!=indexFCI+lenFCI)
		return ERR_EMV_IccDataFormat;
	
	return EMV_OK;

}


/*******************************************************************
×÷    Õß: sxl
º¯ÊýÃû³Æ: unsigned char Paywave_FinalSelectRetData(AppUnionStruct *App_UnionStruct)
º¯Êý¹¦ÄÜ: ½âÎöPaywaveÑ¡ÔñÓ¦ÓÃ·µ»ØÊý¾Ý
Èë¿Ú²ÎÊý: ÎÞ
·µ »Ø Öµ: ÎÞ
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:         20140222
********************************************************************/
unsigned char  Paypassb_FinalSelectRetData(APDU_RESP *apdu_r,EMVBAppUnionStruct *tempApp_UnionStruct)
{
    
    //unsigned char k, i;
    SELECT_RET selectRet;
	LISTAPPDATA *tempselectedapp;
	
	LISTAPPDATA *tempappdata;
	unsigned char tempselectedappno;
	//unsigned char tempselectappno;  
	//unsigned char indexPODL,TermTranFlag;
	unsigned char *tempappnum;
        
        
	tempappnum = &(tempApp_UnionStruct->EMVTradeParam->AppListCandidatenum);
	tempselectedapp = tempApp_UnionStruct->EMVTradeParam->SelectedApp;
	tempappdata = tempApp_UnionStruct->EMVTradeParam->AppListCandidate;
	tempselectedappno = tempApp_UnionStruct->EMVTradeParam->SelectedAppNo;
    
	
	
    
	if(apdu_r->SWA==0x90 && apdu_r->SWB==0x00)//Select OK
	{	
	    
	    Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S53_7);
        
		gEmvballocator.EMVBallocator_memset((unsigned char*)&selectRet,0,sizeof(SELECT_RET));

		if(Paypassb_FinalReadSelectRetData(&selectRet,apdu_r->DataOut,apdu_r->LenOut,tempApp_UnionStruct)!=EMV_OK) 
		{
		    #ifdef EMVB_DEBUG
            emvb_printf("\r\nPaypass_FinalReadSelectRetData111\r\n");
			#endif
		    
			//Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S1_7_0);
            
			return PAYPASS_PARSEERR;
		}

		#ifdef EMVB_DEBUG
        emvb_printf("\r\nPaypass_FinalReadSelectRetData222\r\n");
		#endif
		
		
		if(selectRet.DFNameExist==0 || selectRet.FCIPropExist==0)
		{
			//Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S1_7_1);
            
			return PAYPASS_CARDDATAMISSING;
		}
        
		//±È½ÏÑ¡ÔñµÄÃû³Æ
        
		
		if((tempappdata+tempselectedappno)->AIDLen > selectRet.DFNameLen)
		{
			//Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S1_7_0);
            return PAYPASS_PARSEERR;

		}

		#ifdef EMVB_DEBUG
        emvb_printf("\r\nPaypass_FinalReadSelectRetData555\r\n");
		#endif
        
		if(gEmvballocator.EMVBallocator_memcmp((tempappdata+tempselectedappno)->AID,selectRet.DFName,(tempappdata+tempselectedappno)->AIDLen))
		{
			//Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S1_7_0);
            
			return PAYPASS_PARSEERR;
		}

		#ifdef EMVB_DEBUG
        emvb_printf("\r\nPaypass_FinalReadSelectRetData666\r\n");
		#endif
		
		gEmvballocator.EMVBallocator_memcpy(tempselectedapp->AID,selectRet.DFName,selectRet.DFNameLen);
		tempselectedapp->AIDLen=selectRet.DFNameLen;

        tempselectedapp->ReqKernelID = (tempappdata+tempselectedappno)->ReqKernelID;
		#ifdef EMVB_DEBUG
        emvb_printf("\r\nPaypass_FinalReadSelectRetData777\r\n");
		#endif
		
		
        
		
	}
	else//current app selected fail,delete it from app list and select again.
	{
		if(*tempappnum > 1)  
		{
			return ERR_EMV_AppReselect;
		}
		else 
		{
			return qPBOC_USEPBOC;   //20110804
		}
	}

	
    Paypassb_saveFCIdata(tempApp_UnionStruct,tempselectedapp,apdu_r);
    Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S53_8);
    
	
	//±È½ÏAID£¬½«Ñ¡ÖÐµÄAID¸´ÖÆ¸øTermInfo
	return qPBOC_READAIDPARAMETERS;
	
}


/*******************************************************************
×÷    Õß: sxl
º¯ÊýÃû³Æ: unsigned char Paywave_FinalSelect(AppUnionStruct *App_UnionStruct)
º¯Êý¹¦ÄÜ: PaywaveÓ¦ÓÃ×îÖÕÑ¡Ôñ
Èë¿Ú²ÎÊý: ÎÞ
·µ »Ø Öµ: ÎÞ
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:         20140222
********************************************************************/
unsigned char Paypassb_FinalSelect(EMVBAppUnionStruct *App_UnionStruct)
{
    
	unsigned char retCode;
	APDU_SEND apdu_s;
	APDU_RESP apdu_r;
	unsigned char tempselectappno;
	LISTAPPDATA *tempAppAppData;
    
    
    tempAppAppData = App_UnionStruct->EMVTradeParam->AppListCandidate;
	tempselectappno = App_UnionStruct->EMVTradeParam->SelectedAppNo;
	EMVB_COMMAND_SELECT((tempAppAppData+tempselectappno)->AID,(tempAppAppData+tempselectappno)->AIDLen,0,&apdu_s);
	App_UnionStruct->EMVB_qPBOCIccIsoCommand(&apdu_s,&apdu_r);
    if(apdu_r.ReadCardDataOk != EMV_OK)
    {
        if(App_UnionStruct->EmvErrID->L3 != EMVB_ERRID_L3_STOP)
        {
        	Paypassb_packoutsignal(App_UnionStruct,PAYPASSSTEP_S53_5);
        }
    	return ERR_APP_TIMEOUT;
		
    }
    
	
	retCode = Paypassb_FinalSelectRetData(&apdu_r,App_UnionStruct);
	if(retCode == qPBOC_USEPBOC)
	{
		Paypassb_SetErrPar(App_UnionStruct,PAYPASSSTEP_S53_13);
		Paypassb_SetErrPar(App_UnionStruct,PAYPASSSTEP_S53_14);
		Paypassb_packoutsignal(App_UnionStruct,PAYPASSSTEP_S53_15);
		return PAYPASS_ENDAPPLICATION;
	}
	else if(retCode == PAYPASS_PARSEERR ||retCode == PAYPASS_CARDDATAMISSING)
	{
	     if(retCode == PAYPASS_CARDDATAMISSING)
	     {
	     	Paypassb_SetErrPar(App_UnionStruct,PAYPASSSTEP_S1_7_1);
	     }
		 else
		 {
		 	Paypassb_SetErrPar(App_UnionStruct,PAYPASSSTEP_S1_7_0);
		 }
		 Paypassb_packoutsignal(App_UnionStruct,PAYPASSSTEP_S1_8_0);
		 return ERR_EMV_AppReselect;
	}
	
    return retCode;
    
    
}


/*******************************************************************
×÷    Õß: sxl
º¯ÊýÃû³Æ: unsigned char Paywave_FinalSelectedApp(AppUnionStruct *App_UnionStruct)
º¯Êý¹¦ÄÜ: Ó¦ÓÃ×îÖÕÑ¡Ôñ
Èë¿Ú²ÎÊý: ÎÞ
·µ »Ø Öµ: ÎÞ
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:        20140222
********************************************************************/
unsigned char Paypassb_FinalSelectedApp(EMVBAppUnionStruct *App_UnionStruct)
{
	unsigned char retCode;
	//unsigned short tempnowtask;
    
	
	retCode = Paypassb_FinalSelect(App_UnionStruct);      //Ñ¡ÖÐÓ¦ÓÃ
	if(retCode == ERR_EMV_AppReselect)
	{
	    retCode = EMV_APPSELECTTRYAGAIN;
	}

	return retCode;
	
}



// 20140222
void Paypassb_initEMVobjBeforeGPO(EMVBAppUnionStruct *App_UnionStruct,unsigned char aidindex)
{
    
    unsigned char TermCapab[3];
	EMVTAGCVLITEM *item;
	unsigned char HoldTimeValue;
	unsigned char AmtAuthNum[6];
	unsigned char termcvm_limit[6];
	
    dllemvb_avl_set((unsigned char *)TAG_MobileSupportIndicator,0x01);
	dllemvb_avl_createsettagvalue((unsigned char *)TAG_CVMResult,(unsigned char *)"\x00\x00\x00",3);
	
	App_UnionStruct->EMVTradeParam->gSelectedaidindex = aidindex;
                 
	#if 0	  //sxl20171129		
	if(App_UnionStruct->EMVTradeParam->gPaypassProceFlag[aidindex].TermCFLEF)
	{
	    #ifdef EMVB_DEBUG
        emvb_printf("\r\nPaypassProceFlag[aidindex].TermCFLEF = %d\r\n",App_UnionStruct->EMVTradeParam->gPaypassProceFlag[aidindex].TermCFLEF);
		#endif
		App_UnionStruct->EMVTradeParam->ContactlessTermEFLEF = 1;
	}
	else
	{
		App_UnionStruct->EMVTradeParam->ContactlessTermEFLEF = 0;
	}

	if(App_UnionStruct->EMVTradeParam->gPaypassProceFlag[aidindex].OndevCTLEF)
	{
		App_UnionStruct->EMVTradeParam->PaypassOndevCTLEF = 1;
	}
	else
	{
		App_UnionStruct->EMVTradeParam->PaypassOndevCTLEF = 0;
	}
	#endif

	App_UnionStruct->EMVTradeParam->ODAstaus = 0;
	//20170221
	dllemvb_avl_set((unsigned char *)TAG_RRPCounter,0);
	
	gEmvballocator.EMVBallocator_memset(TermCapab,0,sizeof(TermCapab));

	//dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_TermCapab,TermCapab,0,3);
	TermCapab[0] = dllemvb_avl_gettagvalue((unsigned char *)TAG_CARDINPUTCAP);
    TermCapab[2] = dllemvb_avl_gettagvalue((unsigned char *)TAG_SecurityCapability);

	dllemvb_avl_createsettagvalue((unsigned char *)TAG_TermCapab,TermCapab,3);

	 #ifdef EMVB_DEBUG
     dllemvb_avl_printtagallvalue((unsigned char *)"init pre GPO TAG_TermCapab",(unsigned char *)TAG_TermCapab);
	 #endif
	
    memset(AmtAuthNum,0,sizeof(AmtAuthNum));
    dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AmtAuthNum,AmtAuthNum,0,6);
    memset(termcvm_limit, 0, sizeof(termcvm_limit));
    dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_termcvm_limit,termcvm_limit,0,6);

    if(memcmp(AmtAuthNum, termcvm_limit, 6) > 0 )
	{
	    #ifdef EMVB_DEBUG
        //printfemv("\r\ncvm required \r\n");
		#endif
		App_UnionStruct->EMVTradeParam->ContactlessCVMRLEF = 1;
	}
	else
	{
	    #ifdef EMVB_DEBUG
        emvb_printf("\r\n no cvm required \r\n");
		#endif
		App_UnionStruct->EMVTradeParam->ContactlessCVMRLEF = 0;
	}
    
	//20130118add
	#ifdef EMVB_DEBUG
    //emvb_printf("\r\ngPaypassProceFlag[gSelectedaidindex].TermCTLEF = %d %d%d\r\n",aidindex,App_UnionStruct->EMVTradeParam->gPaypassProceFlag[aidindex].TermCTLEF,App_UnionStruct->EMVTradeParam->gPaypassProceFlag[aidindex].OndevCTLEF);
	#endif
    
	App_UnionStruct->pUserInterfaceReqData->LanguagePreferenceLen = 0;
    item = dllemvb_avl_gettagitempointer((unsigned char *)TAG_LangPrefer);
	if(item != NULL)
	{
	    if(item->len)
	    {
			gEmvballocator.EMVBallocator_memcpy(App_UnionStruct->pUserInterfaceReqData->LanguagePreference,item->data,item->len);
			App_UnionStruct->pUserInterfaceReqData->LanguagePreferenceLen = item->len;
	    }
	}

    App_UnionStruct->pOutParameterSet->FieldoffinoutParameter = 0xFF;
    item = dllemvb_avl_gettagitempointer((unsigned char *)TAG_AppCapabilitiesInfor);
	if(item != NULL)
	{
	    if((item->len)>1)
	    {
	    	if(item->data[1]&0x04)
			{
			    HoldTimeValue = dllemvb_avl_gettagvalue((unsigned char *)TAG_HoldTimeValue);
				App_UnionStruct->pOutParameterSet->FieldoffinoutParameter = HoldTimeValue;
			}
	    }
	}

	#ifdef EMVB_DEBUG
    emvb_printf("\r\ngOutParameterSet.FieldoffinoutParameter = %d\r\n",App_UnionStruct->pOutParameterSet->FieldoffinoutParameter);
	#endif
		
	//20120221 S1.10
	dllemvb_avl_createsettagvalue((unsigned char *)TAG_PaypassDataNeeded,NULL,0);
    dllemvb_avl_createsettagvalue((unsigned char *)TAG_PaypassDataToSend,NULL,0);
	dllemvb_avl_createsettagvalue((unsigned char *)TAG_PAYPSS_TAGSTOREADYET,NULL,0);

	
	if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_TagsToRead))
	{
		Paypassb_AddListToList_T_T((unsigned char *)TAG_TagsToRead,(unsigned char *)TAG_PAYPSS_TAGSTOREADYET);
	}
    else
    {
        if(dllemvb_avl_checkiftagempty((unsigned char *)TAG_TagsToRead))
        {
    		Paypassb_AddDataToList_T((unsigned char *)TAG_TagsToRead,(unsigned char *)TAG_PaypassDataNeeded);
        }
    }


	
}




/*******************************************************************
×÷    Õß: sxl
º¯ÊýÃû³Æ: unsigned char Paywave_PDOLProcess(AppUnionStruct *tempApp_UnionStruct,APDU_SEND *apdu_s)
º¯Êý¹¦ÄÜ: ×éÖ¯·¢ËÍGPOÊý¾Ý
Èë¿Ú²ÎÊý: ÎÞ
·µ »Ø Öµ: ÎÞ
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:    20140222
********************************************************************/
unsigned char Paypassb_PDOLProcess(EMVBAppUnionStruct *tempApp_UnionStruct,APDU_SEND *apdu_s,unsigned char type)
{
	unsigned char *pdolData;   //[255]
	unsigned short index,indexOut;
	unsigned char k,m,*buf,bInTable;  //[255]
	unsigned char len;
	EMVTAGCVLITEM *item;
	//EMVTAGCVLITEM *tempitem;
	unsigned char *PDOL;   //[300]
	unsigned char tag[4],taglen;
	EMVTAGCVLITEM *pdoldataitem;
	//unsigned char tempTermTransPredicable;
	unsigned short templen,tempPDOLlen;
	unsigned char PDOLbexist = 0;
    
	#ifdef EMVB_DEBUG
	unsigned char i;
    #endif
	
	item = dllemvb_avl_gettagitempointer((unsigned char *)TAG_PDOL);
	if(item != NULL)
	{	
		if(item->len)
		{
			PDOLbexist = 1;
		}
	}
    
	
	if(PDOLbexist == 0)
	{
		gEmvballocator.EMVBallocator_memcpy(apdu_s->Command,"\x80\xA8\x00\x00",4); 
		apdu_s->Lc=2;
		gEmvballocator.EMVBallocator_memcpy(apdu_s->DataIn,"\x83\x00",2);
		apdu_s->Le=256;
		apdu_s->EnableCancel = 1;    //ÔÊÐíÈ¡Ïû
		//apdu_s->EnableDET = 1;
		return EMV_OK;
	}
    
	pdolData = (unsigned char *)emvblib_malloc(255);
	buf = (unsigned char *)emvblib_malloc(255);
	PDOL = (unsigned char *)emvblib_malloc(300);
	//PDOL Îª¿Õ
	gEmvballocator.EMVBallocator_memset(pdolData,0,255);
	
	#ifdef EMVB_DEBUG
    emvb_printf("\r\nPaywaveb_PDOLProcess\r\n");
    for(i = 0;i < item->len;i++)
    {
    	emvb_printf("%02x ",item->data[i]);
    }
	emvb_printf("\r\n");
	#endif
    
	index=0;
	indexOut=0;
    
    
	gEmvballocator.EMVBallocator_memset(PDOL,0,300);
    if(item->len>255)
    {
    	tempPDOLlen = 255;
    }
    else
    {
    	tempPDOLlen = item->len;
    }
    gEmvballocator.EMVBallocator_memcpy(PDOL,item->data,tempPDOLlen);
	
	
    
	while(index<tempPDOLlen)//Process PDOL
	{
		if(PDOL[index]==0xFF || PDOL[index]==0x00) {index++; continue;} 
		gEmvballocator.EMVBallocator_memset(buf,0,255);
		bInTable=0;


		gEmvballocator.EMVBallocator_memset(tag,0,sizeof(tag));
		taglen = 0;
		tag[taglen++] = PDOL[index];
		if((tag[0]&0x1f) == 0x1f)
		{
			tag[taglen++] = PDOL[index+1];
			if(tag[1]&0x80)
			{
				tag[taglen++] = PDOL[index+2];
			}
		}

		
		//Èç¹ûÊÇPDOLÐèÒªµÄÊý¾ÝÈ±Ê§µÄ,¾Í²»ÍùÏÂ×ßÁË£¬Ö±½Ó¿´ÊÇ·ñÒªÇëÇóÊý¾Ý
        //S1.12
		if(tempApp_UnionStruct->EMVTradeParam->paypassMissingPDOLDataFlag)
		{
		    if(dllemvb_avl_checkiftagempty(tag))
		    {
		        Paypassb_checkifneedaddtodataneed(tag,taglen);
		    }
			index += taglen+1;  //Òª¿´ÕâÀïÊÇ·ñ»áÓÐÁ½¸ö×Ô¼ºÊý¾Ý³¤¶ÈµÄ
			continue;
		}
        else if(PDOL[index+taglen] > 0 &&dllemvb_avl_checkiftagempty(tag))//&&(dllemvb_avl_checkiftagexist(TAG_DSVNTerm)||dllemvb_avl_checkiftagexist(TAG_ProfirstWF)||dllemvb_avl_gettagitempointer(TAG_TagsToRead) != NULL||dllemvb_avl_gettagitempointer(TAG_DSOperatorID) != NULL)
        {
            if(Paypassb_checkifneedaddtodataneed(tag,taglen))
            {
	        	tempApp_UnionStruct->EMVTradeParam->paypassMissingPDOLDataFlag = 1;
				if(type)
				{
				    emvblib_free(pdolData);
				    emvblib_free(buf);
				    emvblib_free(PDOL);
					return EMV_ERR;
				}
				continue;
            }
        }
        
		
		pdoldataitem = dllemvb_avl_gettagitempointer(tag);
        
		
		if(pdoldataitem != NULL)
		{
		    index += taglen;
            
			if((index+1)>tempPDOLlen)
			{
			    emvblib_free(pdolData);
			    emvblib_free(buf);
			    emvblib_free(PDOL);
				return ERR_EMV_IccDataFormat;
			}
			templen = PDOL[index++];
			
			
            k = templen;   // 1
			m=pdoldataitem->len; // 4
			
			#if 0
			if(gEmvballocator.EMVBallocator_memcmp(tag,"\x9F\x5C",2) == 0&&k == 0)
			{
				k = 8; //ÐèÒªÊäÈë8¸ö×Ö½Ú
			}
			
			else if(tag[0] == 0xC7&&k == 0)
			{
				tempitem = dllemvb_avl_gettagitempointer(tag);
				if(tempitem != NULL)
				{
					k = tempitem->len;
				}
				
			}
			#endif
			
			if(pdoldataitem->datafomat&TAGFORMAT_N)//numeric
			{
				if(k>=m){
					if(m)
					{
						gEmvballocator.EMVBallocator_memcpy(&buf[k-m],pdoldataitem->data,m);
					}
					gEmvballocator.EMVBallocator_memcpy(&pdolData[indexOut],buf,k);
				}
				else{
					if(m)
					{
						gEmvballocator.EMVBallocator_memcpy(buf,pdoldataitem->data,m);
					}
					gEmvballocator.EMVBallocator_memcpy(&pdolData[indexOut],&buf[m-k],k);
				}
			}
			else if(pdoldataitem->datafomat&TAGFORMAT_CN)//compact numeric
			{
			    if(m)
			    {
					gEmvballocator.EMVBallocator_memset(buf,0xFF,255);
					gEmvballocator.EMVBallocator_memcpy(buf,pdoldataitem->data,m);
					gEmvballocator.EMVBallocator_memcpy(&pdolData[indexOut],buf,k);
			    }
				else
				{
					gEmvballocator.EMVBallocator_memset(buf,0x00,255);
					gEmvballocator.EMVBallocator_memcpy(&pdolData[indexOut],buf,k);
				}
			}
			else//other formats
			{
			    if(m)
			    {
					gEmvballocator.EMVBallocator_memcpy(buf,pdoldataitem->data,m);
			    }
				gEmvballocator.EMVBallocator_memcpy(&pdolData[indexOut],buf,k);
			}


			indexOut+=k;
			bInTable=1;
		}
		
		if(!bInTable)
		{
			index += taglen;
			if((index+1)>tempPDOLlen)
			{
			    emvblib_free(pdolData);
			    emvblib_free(buf);
			    emvblib_free(PDOL);
				return ERR_EMV_IccDataFormat;
			}
			templen = PDOL[index++];
			/*
			if(ParseExtLen(PDOL,&index,&templen))
			{
			    emvblib_free(pdolData);
				emvblib_free(buf);
				emvblib_free(PDOL);
				return ERR_EMV_IccDataFormat;
			}
			*/
			k = templen;
			gEmvballocator.EMVBallocator_memcpy(&pdolData[indexOut],buf,k);
			indexOut+=k;
			
			
		}

		#ifdef EMVB_DEBUG
        emvb_printf("\r\nPDOL tag:%d\r\n",taglen);
		for(i = 0;i < taglen;i++)
		{
			emvb_printf("%02x ",tag[i]);
		}
		emvb_printf("\r\n");
		#endif
	}
	// Process PDOL end here

    //S1.13
	if(tempApp_UnionStruct->EMVTradeParam->paypassMissingPDOLDataFlag == 0)
	{
		dllemvb_avl_createsettagvalue((unsigned char *)TAG_PDOLData,pdolData,indexOut);
		
		//tempterminfo->PDOLDataLen=indexOut;
		//gEmvballocator.EMVBallocator_memcpy(tempterminfo->PDOLData,pdolData,indexOut);
	    
	    
	    
		
		gEmvballocator.EMVBallocator_memcpy(apdu_s->Command,"\x80\xA8\x00\x00",4);
		apdu_s->Lc=indexOut+2;
		len = 0;
		apdu_s->DataIn[len++]=0x83;

		if((indexOut&0x80)>0)				 //ÓÐÁ½¸ö×Ö½Ú
		{
			(apdu_s->Lc)++;
			apdu_s->DataIn[len++]=0x81;
			apdu_s->DataIn[len++]=indexOut;   //Ö»ÓÐÒ»¸ö×Ö½Ú
		}
		else
		{
			apdu_s->DataIn[len++]=indexOut;   //Ö»ÓÐÒ»¸ö×Ö½Ú
		}
	    
		
		gEmvballocator.EMVBallocator_memcpy((unsigned char*)&apdu_s->DataIn[len],pdolData,indexOut);
		apdu_s->Le=256;
		apdu_s->EnableCancel = 1;    //ÔÊÐíÈ¡Ïû
	}

	emvblib_free(pdolData);
	emvblib_free(buf);
	emvblib_free(PDOL);
	
	return EMV_OK;

	
}


/*******************************************************************
×÷    Õß:
º¯ÊýÃû³Æ: unsigned char Emv_GPORetData(AppUnionStruct *tempApp_UnionStruct,APDU_RESP *apdu_r)
º¯Êý¹¦ÄÜ: ½âÎöGPO»ØµÄÊý¾Ý
Èë¿Ú²ÎÊý: ÎÞ
·µ »Ø Öµ: ÎÞ
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:         20140222
********************************************************************/
unsigned char PayPassb_GPORetData(EMVBAppUnionStruct *tempApp_UnionStruct,APDU_RESP *apdu_r)
{
	unsigned short index,indexTemp,len,lenTemp,cplen,j;
    unsigned char k;  //i,
	unsigned char bInTable;
	//unsigned int unknowlen;
	//unsigned char tag;
	unsigned char ret;
    EMVTAGCVLITEM *item;
    
	
    
	if(apdu_r->SWA==0x90 && apdu_r->SWB==0x00) //Get Processing Options OK
	{		
		index=0;
		//Êý¾Ý¸ñÊ½Îª:¡®80¡¯+³¤¶È+AIP(Ó¦ÓÃ½»»¥ÌØÕ÷)+AFL(Ã¿4¸ö×Ö½ÚÊÇÒ»×éÎÄ¼þ¶¨Î»Æ÷)
		if(apdu_r->DataOut[index]==0x80)//primitive data
		{	
			if(apdu_r->LenOut<6)
			{
				return ERR_EMV_IccDataFormat;
			}
			index++;
            if(ParseExtLen(apdu_r->DataOut,&index,&len))
            {
            	return ERR_EMV_IccDataFormat;
            }
			
			if(index+len!=apdu_r->LenOut)
				return ERR_EMV_IccDataFormat;

			if(len < 2)
			{
				return PAYPASS_ENDAPPLICATION;
			}

			if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_AIP))
			{
				return PAYPASS_ENDAPPLICATION;
			}

			dllemvb_avl_createsettagvalue((unsigned char *)TAG_AIP,apdu_r->DataOut+index,2);
            
			
			index+=2;
			k = (len-2)%4;
			if(k != 0)
			{
				return ERR_EMV_IccDataFormat;
			}
			k=(len-2)/4;//AFL4×Ö½Ú³¤¶È
			cplen = ((unsigned short)k)*4;

            if(cplen)
            {
	            if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_AFL))
				{
					return PAYPASS_ENDAPPLICATION;
				}
				dllemvb_avl_createsettagvalue((unsigned char *)TAG_AFL,apdu_r->DataOut+index,cplen);
            }
			
		    
			for(j = 0;j<k;j++)
			{
				if(apdu_r->DataOut[index + j*4] == 0)
				{
					return ERR_EMV_IccDataFormat;
				}
			}
			
			index += cplen;		
		}
		else if(apdu_r->DataOut[index]==0x77)//TLV coded data
		{
		    tempApp_UnionStruct->EMVTradeParam->paywavecvntype = 1;
            
			
			index++;
			if(ParseExtLen(apdu_r->DataOut,&index,&lenTemp))
			{
				return ERR_EMV_IccDataFormat;
			}
			
			indexTemp=index;
			while(index<indexTemp+lenTemp)
			{
				if(index>=apdu_r->LenOut) 
				{
					return ERR_EMV_IccDataFormat;
				}
				if(apdu_r->DataOut[index]==0xFF || apdu_r->DataOut[index]==0x00) { index++; continue;}
                ret = Paypassb_ParseAndStoreCardResponse(tempApp_UnionStruct,apdu_r->DataOut,&index,&bInTable,1);
				if(ret != EMV_OK)
				{
					return ERR_EMV_IccDataFormat;
				}
          
				
				
			}
			if(index!=indexTemp+lenTemp)
			{
				return PAYPASS_ENDAPPLICATION;
			}	

			//add AFL data to check
			item = dllemvb_avl_gettagitempointer((unsigned char *)TAG_AFL);
			if(item != NULL)
			{
				if((item->len < 4)||((item->len % 4)!=0))
				{
					return PAYPASS_ENDAPPLICATION;
				}
			}

			item = dllemvb_avl_gettagitempointer((unsigned char *)TAG_AIP);
			if(item != NULL)
			{
				if(item->len != 2)
				{
					return PAYPASS_ENDAPPLICATION;
				}
			}
			
		}
		else return PAYPASS_ENDAPPLICATION;
		
	}
	else
	{
	   //S3.8
		return ERR_EMVINITAPP_NOTACCEPED;
	}
	
    if(index != apdu_r->LenOut)
    {
    	return PAYPASS_ENDAPPLICATION;
    }


	if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_AFL)==0 || dllemvb_avl_checkiftagexist((unsigned char *)TAG_AIP)==0)
	{
	    //S3.14
		return PAYPASS_CARDDATAMISSING;
	}
	

	
	
	return EMV_OK;
}


/*******************************************************************
×÷    Õß: sxl
º¯ÊýÃû³Æ: unsigned char Paypass_InitialApp(AppUnionStruct *tempApp_UnionStruct)
º¯Êý¹¦ÄÜ: Ó¦ÓÃ³õÊ¼»¯
Èë¿Ú²ÎÊý: ÎÞ
·µ »Ø Öµ: ÎÞ
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:         20140222
********************************************************************/
unsigned char Paypassb_InitialApp(EMVBAppUnionStruct *tempApp_UnionStruct)
{
	unsigned char retCode;
	unsigned char AIP[2],KernelConfigure;
    EMVTAGCVLITEM *emvitem;
	
	APDU_SEND apdu_s;
	APDU_RESP apdu_r;

	
	
    tempApp_UnionStruct->EMVTradeParam->ODASMstaus = 0;
	//S1.11
	tempApp_UnionStruct->EMVTradeParam->paypassMissingPDOLDataFlag = 0;
	retCode = Paypassb_PDOLProcess(tempApp_UnionStruct,&apdu_s,0);
    #ifdef EMVB_DEBUG
    emvb_printf("\r\nPaypassb_PDOLProcess retCode = %d\r\n",retCode);
	#endif
	if(retCode != EMV_OK)
	{
		return retCode;
	}

	#ifdef EMVB_DEBUG
    //emvb_printf("po1:%d",dev_user_gettimeID());
	#endif
    
    //S1.15
	Paypassb_AddTLVToList_RemoveTag((unsigned char *)TAG_PAYPSS_TAGSTOREADYET,(unsigned char *)TAG_PaypassDataToSend);
    //S1.16
    dllemvb_avl_set((unsigned char *)TAG_IDSStatus,0);
	dllemvb_avl_set((unsigned char *)TAG_DSSummaryStatus,0);
    dllemvb_avl_set((unsigned char *)TAG_POSTGACPDS,0);
	dllemvb_avl_set((unsigned char *)TAG_PREGACPDS,0);
	dllemvb_avl_createsettagvalue((unsigned char *)TAG_DSDigestH,(unsigned char *)"\x00\x00\x00\x00\x00\x00\x00\x00",8);
	dllemvb_avl_createsettagvalue((unsigned char *)TAG_PAYPSS_TAGSWYETAGAC,NULL,0);
	dllemvb_avl_createsettagvalue((unsigned char *)TAG_PAYPSS_TAGSWYETBGAC,NULL,0);
	if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_WriteBeforeGAC))
	{
		Paypassb_AddListToList_TLV_TLV((unsigned char *)TAG_WriteBeforeGAC,(unsigned char *)TAG_PAYPSS_TAGSWYETBGAC);
	}
	else
	{
	    if(dllemvb_avl_checkiftagempty((unsigned char *)TAG_WriteBeforeGAC))
	    {
			Paypassb_AddDataToList_T((unsigned char *)TAG_WriteBeforeGAC,(unsigned char *)TAG_PaypassDataNeeded);
	    }
	}

	
	if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_WriteAfterGAC))
	{
		Paypassb_AddListToList_TLV_TLV((unsigned char *)TAG_WriteAfterGAC,(unsigned char *)TAG_PAYPSS_TAGSWYETAGAC);
	}
	else
	{
	    if(dllemvb_avl_checkiftagempty((unsigned char *)TAG_WriteAfterGAC))
	    {
			Paypassb_AddDataToList_T((unsigned char *)TAG_WriteAfterGAC,(unsigned char *)TAG_PaypassDataNeeded);
	    }
	}

	//S1.17
	if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_DSVNTerm)&&dllemvb_avl_gettagitempointer((unsigned char *)TAG_DSOperatorID) != NULL)
	{
		//S1.18
		emvitem = dllemvb_avl_gettagitempointer((unsigned char *)TAG_DSID);
		if(emvitem != NULL)
		{
			Paypassb_AddDataToList_TLV((unsigned char *)TAG_DSID,emvitem->data,emvitem->len,(unsigned char *)TAG_PaypassDataToSend);
		}
		else
		{
			Paypassb_AddDataToList_TLV((unsigned char *)TAG_DSID,NULL,0,(unsigned char *)TAG_PaypassDataToSend);
		}

		emvitem = dllemvb_avl_gettagitempointer((unsigned char *)TAG_AppCapabilitiesInfor);
		if(emvitem != NULL)
		{
			Paypassb_AddDataToList_TLV((unsigned char *)TAG_AppCapabilitiesInfor,emvitem->data,emvitem->len,(unsigned char *)TAG_PaypassDataToSend);
            //S1.19
            if(emvitem->len)
            {
            	if(((emvitem->data[0]&0x0f) == 0x01||(emvitem->data[0]&0x0f) == 0x02)&&dllemvb_avl_checkiftagexist((unsigned char *)TAG_DSID))
            	{
            	    //S1.20
            	    //SET 'Read' in IDS Status
            		dllemvb_avl_set((unsigned char *)TAG_IDSStatus,dllemvb_avl_gettagvalue((unsigned char *)TAG_IDSStatus)|0x80);
            	}
            }
		}
		else
		{
			Paypassb_AddDataToList_TLV((unsigned char *)TAG_AppCapabilitiesInfor,NULL,0,(unsigned char *)TAG_PaypassDataToSend);
		}
		
	}
	
	
	//S1.21
	if(tempApp_UnionStruct->EMVTradeParam->paypassMissingPDOLDataFlag)
	{
		//S1.22
		retCode = paypassb_SendDEKSignal(tempApp_UnionStruct,PAYPASSSTEP_S1_22_0,&apdu_s);
		if(retCode == qPBOC_RESETCOMMAND)
		{
			Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S2_4_0);
			return PAYPASS_ENDAPPLICATION;
		}
		else if(retCode != EMV_OK)
		{
			Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S2_3_0);
			return PAYPASS_ENDAPPLICATION;
		}
		
	}

	#ifdef EMVB_DEBUG
    //emvb_printf("po2:%d",dev_user_gettimeID());
	#endif
	
	//if(tempApp_UnionStruct->EMVTradeParam->paypassMissingPDOLDataFlag == 0)
    {
        //S1.14
    	tempApp_UnionStruct->EMVB_qPBOCIccIsoCommand(&apdu_s,&apdu_r);
    }
	
    if(apdu_r.ReadCardDataOk != EMV_OK)
    {
        if(tempApp_UnionStruct->EmvErrID->L3 != EMVB_ERRID_L3_STOP)
        {
	    	Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S3_4_0);
			Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S3_5_0);
        }
		return PAYPASS_ENDAPPLICATION;
    }
    
	retCode = PayPassb_GPORetData(tempApp_UnionStruct,&apdu_r);
	if(retCode == ERR_EMVINITAPP_NOTACCEPED)
	{
	    //S3.9.1
		Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S3_9_1);
		Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S3_9_2);
	}
	else if(retCode != EMV_OK)
	{
		if(retCode == PAYPASS_CARDDATAMISSING)
        {
        	Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S3_14_0);
        }
		else
		{
			Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S3_12_0);
		} 
		Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S3_90_1);
		Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S3_90_2);
	}
    
	
	if(retCode == EMV_OK)
	{
		gEmvballocator.EMVBallocator_memset(AIP,0,sizeof(AIP));
		dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AIP,AIP,0,2);
        KernelConfigure = dllemvb_avl_gettagvalue((unsigned char *)TAG_KernelConfiguration);
        //S3.15
		if(KernelConfigure&0x40) //terminal only mag mode
		{
		    //S3.17
			if(KernelConfigure&0x80) //terminal only sup EMV
			{
			    //S3.18
			    Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S3_18);
				Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S3_90_1);
		        Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S3_90_2);
				retCode = PAYPASS_ENDAPPLICATION;
			}
			else
			{
			    //S3.B
				tempApp_UnionStruct->EMVTradeParam->qPBOCOrMSD = MSDTYPE;
			}
		}
		else
		{
			if(AIP[1]&0x80) //card support EMV
			{
			    //S3.A
				tempApp_UnionStruct->EMVTradeParam->qPBOCOrMSD = qPBOCTYPE;
			}
			else   //card not support EMV
			{
				if(KernelConfigure&0x80) //terminal only sup EMV
				{
				    Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S3_18);
					Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S3_90_1);
			        Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S3_90_2);
					retCode = PAYPASS_ENDAPPLICATION;
				}
				else
				{
				    //S3.B
					tempApp_UnionStruct->EMVTradeParam->qPBOCOrMSD = MSDTYPE;
				}
			}
		}
	}

    return retCode;
    
}




/*******************************************************************
×÷    Õß: sxl
º¯ÊýÃû³Æ: unsigned char Paywave_ReadAFLRetData(AppUnionStruct *tempApp_UnionStruct,APDU_RESP *apdu_r,unsigned char *tempRead_AFL_Num,unsigned char *tempAFL_RecordNum)
º¯Êý¹¦ÄÜ: ¶ÁAFL·µ»ØµÄÊý¾Ý½âÎö
Èë¿Ú²ÎÊý: ÎÞ
·µ »Ø Öµ: ÎÞ
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:     20140222
********************************************************************/
unsigned char Paypassb_ReadAFLRetData(EMVBAppUnionStruct *tempApp_UnionStruct,APDU_RESP *apdu_r,unsigned char tempt,unsigned char authdataflag)
{
	unsigned char t;
	unsigned char bInTable;  //i,k,
	unsigned short index,indexAEF,lenAEF;  //len,
	//unsigned char tempreadaflnum;
	//unsigned char tag;
	unsigned char ret;
    
	
	if(!(apdu_r->SWA==0x90 && apdu_r->SWB==0x00)) // ICC parameter Records found fail.
	{
		return PAYPASS_SW1SW2ERR;   //
	}

	//?2017 S4.11   S4.12  S4.13
	
	
	index=0;

	t=tempt;
	t>>=3;
	if((t>=11) && (t<=30))//mofified according to SU Bullitin No.12
	{
	    if(tempApp_UnionStruct->EMVTradeParam->ODAstaus)
	    {
			if(authdataflag)
			{
				if(apdu_r->DataOut[index]==0x70) //¶ÔÓÚSFI´Ó11µ½30µÄ¼ÇÂ¼TAG==70ºÍ¼ÇÂ¼³¤¶ÈÓÃÓÚÍÑ»úÈÏÖ¤
				{	
					if((tempApp_UnionStruct->EMVTradeParam->AuthDataLen+apdu_r->LenOut)>2048)// ·ÀÖ¹ÄÚ´æ³ö´í
					{
						//return ERR_EMV_IccDataFormat;
						tempApp_UnionStruct->EMVTradeParam->bErrAuthData=1;
						return EMV_OK;
					}
					gEmvballocator.EMVBallocator_memcpy((unsigned char*)&tempApp_UnionStruct->EMVTradeParam->AuthData[tempApp_UnionStruct->EMVTradeParam->AuthDataLen],apdu_r->DataOut,apdu_r->LenOut);
					tempApp_UnionStruct->EMVTradeParam->AuthDataLen+=apdu_r->LenOut;
				}
				else//²»µÈÓÚ70ÔòÈÏÎªÍÑ»úÊý¾ÝÈÏÖ¤ÒÑ¾­Ö´ÐÐ²¢Ê§°Ü
				{
					tempApp_UnionStruct->EMVTradeParam->bErrAuthData=1;
				}
			}
	    }
		return EMV_OK;
	}
			

	while(apdu_r->DataOut[index]==0xFF || apdu_r->DataOut[index]==0x00)
	{ 
		index++; 
	}

	if(apdu_r->DataOut[index]!=0x70) 
	{				
		return ERR_EMV_IccDataFormat;
	}
	index++;

	if(ParseExtLen(apdu_r->DataOut,&index,&lenAEF))
	{
		return ERR_EMV_IccDataFormat;
	}

	if(tempApp_UnionStruct->EMVTradeParam->ODAstaus)
	{
		if(authdataflag) //add record to authentication data string if it is required.
		{
		    if((tempApp_UnionStruct->EMVTradeParam->AuthDataLen+lenAEF)>2048)// ·ÀÖ¹ÄÚ´æ³ö´í
			{
				//return ERR_EMV_IccDataFormat;
				tempApp_UnionStruct->EMVTradeParam->bErrAuthData=1;
			}
			else
			{
				gEmvballocator.EMVBallocator_memcpy((unsigned char*)&tempApp_UnionStruct->EMVTradeParam->AuthData[tempApp_UnionStruct->EMVTradeParam->AuthDataLen],(unsigned char*)&apdu_r->DataOut[index],lenAEF);
				tempApp_UnionStruct->EMVTradeParam->AuthDataLen+=lenAEF;
			}
		}
	}

	indexAEF=index;

	
	while(index<indexAEF+lenAEF)
	{
		if(index>=apdu_r->LenOut) 
		{					
			return ERR_EMV_IccDataFormat;
		}
		if(apdu_r->DataOut[index]==0xFF || apdu_r->DataOut[index]==0x00) 
		{ 
			index++; 
			continue;
		}
        
		
		ret = Paypassb_ParseAndStoreCardResponse(tempApp_UnionStruct,apdu_r->DataOut,&index,&bInTable,3);
		if(ret != EMV_OK)
		{
			return ERR_EMV_IccDataFormat;
		}
	}
	if(index!=indexAEF+lenAEF)
	{
		return ERR_EMV_IccDataFormat;
	}

     //20110325
	if(index<apdu_r->LenOut)
	{
		return ERR_EMV_IccDataFormat;
	}
	

	
	return EMV_OK;
}


/*******************************************************************
×÷    Õß:
º¯ÊýÃû³Æ: unsigned char DealPaypassAFLData(AppUnionStruct *tempApp_UnionStruct,APDU_SEND *apdu_s,unsigned char *tempRead_AFL_Num,unsigned char *tempAFL_RecordNum)
º¯Êý¹¦ÄÜ: ´¦ÀíPAYPASS AFL Êý¾Ý
Èë¿Ú²ÎÊý: ÎÞ
·µ »Ø Öµ: ÎÞ
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:         20140222
********************************************************************/
unsigned char DealPaypassbAFLData(EMVBAppUnionStruct *tempApp_UnionStruct)
{
	unsigned char i,j,tmpvalue;
	unsigned char tmp[160],track2pan[19],track2panlen,track2expirydate[2];
	unsigned char track1pan[19],track1panlen,track1expirydate[2],separator;
	unsigned int tmplen;

	unsigned char ktrack2,ttrack2,nun,qtrack2,ktrack1,ttrack1,qtrack1;

    unsigned char PAYPASSTRACK2DATAbExist = 0,PAYPASSPUNATCTRACK2bExist = 0;
	unsigned char PAYPASSPCVC3TRACK2bExist = 0,PAYPASSNATCTRACK2bExist = 0;
    EMVTAGCVLITEM *PAYPASSTRACK2DATAitem = NULL,*PAYPASSPUNATCTRACK2item = NULL,*PAYPASSPCVC3TRACK2item = NULL;
    EMVTAGCVLITEM *PAYPASSNATCTRACK2item = NULL;

	unsigned char PAYPASSTRACK1DATAbExist = 0,PAYPASSNATCTRACK1bExist = 0;
	unsigned char PAYPASSPUNATCTRACK1bExist = 0,PAYPASSPCVC3TRACK1bExist = 0;
	EMVTAGCVLITEM *PAYPASSTRACK1DATAitem = NULL,*PAYPASSNATCTRACK1item = NULL,*PAYPASSPUNATCTRACK1item = NULL,*PAYPASSPCVC3TRACK1item = NULL;
    EMVTAGCVLITEM *item = NULL;
    unsigned char TagbExist;
	unsigned char AIP[2];
    
    #ifdef SXL_DEBUG
    
    emvb_printf("\r\nAFLdata-tempterminfo->qPBOCOrMSD = %d\r\n",tempApp_UnionStruct->EMVTradeParam->qPBOCOrMSD);
    
	#endif
	
	if(tempApp_UnionStruct->EMVTradeParam->qPBOCOrMSD == MSDTYPE) //mag stripe
	{
	    PAYPASSTRACK2DATAitem = dllemvb_avl_gettagitempointerandexiststatus((unsigned char *)TAG_PaypassMagTrack2,&PAYPASSTRACK2DATAbExist);
        PAYPASSPUNATCTRACK2item = dllemvb_avl_gettagitempointerandexiststatus((unsigned char *)TAG_PaypassPunatcTrack2,&PAYPASSPUNATCTRACK2bExist);
        PAYPASSPCVC3TRACK2item = dllemvb_avl_gettagitempointerandexiststatus((unsigned char *)TAG_PaypassPcvc3Track2,&PAYPASSPCVC3TRACK2bExist);
        PAYPASSNATCTRACK2item = dllemvb_avl_gettagitempointerandexiststatus((unsigned char *)TAG_PaypassNatcTrack2,&PAYPASSNATCTRACK2bExist);
		
	
		if(PAYPASSTRACK2DATAbExist==0 ||
			PAYPASSPUNATCTRACK2bExist==0||
			PAYPASSPCVC3TRACK2bExist==0||
			PAYPASSNATCTRACK2bExist==0)
		{
		    #ifdef EMVB_DEBUG
            emvb_printf("\r\nDealPaypassAFLData1111 %d %d %d %d\r\n",PAYPASSTRACK2DATAbExist,PAYPASSPUNATCTRACK2bExist,PAYPASSPCVC3TRACK2bExist,PAYPASSNATCTRACK2bExist);
			#endif
			return ERR_EMV_IccDataMissing;  //sxl
		}

		#ifdef EMVB_DEBUG
        emvb_printf("\r\nDealPaypassAFLDataafaafdd1\r\n");
		#endif

        ktrack2 = 0;
	        for(i = 0;i<2;i++)
	        {
	            tmpvalue = PAYPASSPUNATCTRACK2item->data[i];
				for(j = 0;j<8;j++)
				{
					if(tmpvalue&0x80)
					{
						ktrack2++;
					}
					tmpvalue = tmpvalue<<1;
				}
	        }
		ttrack2 = PAYPASSNATCTRACK2item->data[0];

		#ifdef EMVB_DEBUG
        emvb_printf("\r\nDealPaypassAFLDataafaafdd5\r\n");
		#endif

		if(ktrack2 < ttrack2)
		{
		    #ifdef EMVB_DEBUG
            emvb_printf("\r\nDealPaypassAFLData2222\r\n");
			#endif
			return ERR_EMV_IccDataFormat;
		}

		nun = ktrack2 - ttrack2;

		if(nun > 8)
		{
		    #ifdef EMVB_DEBUG
            emvb_printf("\r\nDealPaypassAFLData2222\r\n");
			#endif
			return ERR_EMV_IccDataFormat;
		}

		tempApp_UnionStruct->EMVTradeParam->PaypassnUN = nun;

        #ifdef EMVB_DEBUG
        emvb_printf("\r\nDealPaypassAFLDataafaafdd6\r\n");
		#endif
		
		qtrack2 = 0;
		for(i = 0;i<2;i++)
        {
            tmpvalue = PAYPASSPCVC3TRACK2item->data[i];
			for(j = 0;j<8;j++)
			{
				if(tmpvalue&0x80)
				{
					qtrack2++;
				}
				tmpvalue = tmpvalue<<1;
			}
        }
		#if 0   //3C06-1000 
        if(qtrack2 < 3)
        {
            #ifdef EMVB_DEBUG
            emvb_printf("\r\nDealPaypassAFLData3333\r\n");
			#endif
        	return ERR_EMV_IccDataFormat;
        }
		#endif


		#ifdef EMVB_DEBUG
        emvb_printf("\r\nDealPaypassAFLDataafaafdd2\r\n");
		emvb_printf("\r\n%d\r\n",PAYPASSTRACK2DATAitem->len);
		#endif
		//check PAN and expiry date
		gEmvballocator.EMVBallocator_memset(tmp,0,sizeof(tmp));
		EMVBcdToAsc(tmp,PAYPASSTRACK2DATAitem->data,PAYPASSTRACK2DATAitem->len);
		tmplen = (PAYPASSTRACK2DATAitem->len)<<1;

        track2panlen = 0;
		gEmvballocator.EMVBallocator_memset(track2pan,0,sizeof(track2pan));
		gEmvballocator.EMVBallocator_memset(track2expirydate,0,sizeof(track2expirydate));
		separator = 0;
		#ifdef EMVB_DEBUG
        emvb_printf("\r\ntmplen = %d\r\n",tmplen);
		#endif
		for(i = 0;i<tmplen;i++)
		{
			if(tmp[i] == 'D')
			{
			    separator = 1;
				if(i>19)
				{
				    #ifdef EMVB_DEBUG
		            emvb_printf("\r\nDealPaypassAFLData8888\r\n");
					#endif
					return ERR_EMV_IccDataFormat;
				}
				gEmvballocator.EMVBallocator_memcpy(track2pan,tmp,i);
				track2panlen = i;
				EMVAscToBcd(track2expirydate,&tmp[i+1],4);
				break;
			}
		}

		#ifdef EMVB_DEBUG
        emvb_printf("\r\ntmplenafaf = %d\r\n",separator);
		#endif

        //Track 2 sent by the card does not include the needed separator so that the discretionary data
        //field cannot be localized.
		if(separator == 0)
		{
		    #ifdef EMVB_DEBUG
		            emvb_printf("\r\nDealPaypassAFLData888kkk\r\n");
					#endif
			return ERR_EMV_IccDataFormat;
		}

        PAYPASSTRACK1DATAitem = dllemvb_avl_gettagitempointerandexiststatus((unsigned char *)TAG_PayPassTrack1Data,&PAYPASSTRACK1DATAbExist);
        PAYPASSNATCTRACK1item = dllemvb_avl_gettagitempointerandexiststatus((unsigned char *)TAG_Paypassnatctrack1,&PAYPASSNATCTRACK1bExist);
        PAYPASSPUNATCTRACK1item = dllemvb_avl_gettagitempointerandexiststatus((unsigned char *)TAG_PaypassPunatcTrack1,&PAYPASSPUNATCTRACK1bExist);
        PAYPASSPCVC3TRACK1item = dllemvb_avl_gettagitempointerandexiststatus((unsigned char *)TAG_PaypassPCVC3Track1,&PAYPASSPCVC3TRACK1bExist);

		//track1 data exist
		if(PAYPASSTRACK1DATAbExist)
		{
			if(PAYPASSNATCTRACK1bExist==0 ||
			PAYPASSPUNATCTRACK1bExist==0||
			PAYPASSPCVC3TRACK1bExist==0)
			{
			    #ifdef EMVB_DEBUG
	            emvb_printf("\r\nDealPaypassAFLData4444\r\n");
				#endif
				return ERR_EMV_IccDataFormat;
			}

			ktrack1 = 0;
			for(i = 0;i<6;i++)
			{
				tmpvalue = PAYPASSPUNATCTRACK1item->data[i];
				for(j = 0;j<8;j++)
				{
					if(tmpvalue&0x80)
					{
						ktrack1++;
					}
					tmpvalue = tmpvalue<<1;
				}
			}
			ttrack1 = PAYPASSNATCTRACK1item->data[0];

			if(ktrack1 < ttrack1)
			{
			    #ifdef EMVB_DEBUG
	            emvb_printf("\r\nDealPaypassAFLData5555\r\n");
				#endif
				return ERR_EMV_IccDataFormat;
			}

			if(nun != (ktrack1 - ttrack1))
			{
			    #ifdef EMVB_DEBUG
	            emvb_printf("\r\nDealPaypassAFLData6666\r\n");
				#endif
				return ERR_EMV_IccDataFormat;
			}

			qtrack1 = 0;
			for(i = 0;i<6;i++)
	        {
	            tmpvalue = PAYPASSPCVC3TRACK1item->data[i];
				for(j = 0;j<8;j++)
				{
					if(tmpvalue&0x80)
					{
						qtrack1++;
					}
					tmpvalue = tmpvalue<<1;
				}
	        }
			#if 0  //3C06-1000
	        if(qtrack1 < 3)
	        {
	            #ifdef EMVB_DEBUG
	            emvb_printf("\r\nDealPaypassAFLData7777\r\n");
				#endif
	        	return ERR_EMV_IccDataFormat;
	        }
			#endif
			

			gEmvballocator.EMVBallocator_memset(tmp,0,sizeof(tmp));
			gEmvballocator.EMVBallocator_memcpy(tmp,PAYPASSTRACK1DATAitem->data,PAYPASSTRACK1DATAitem->len);
			tmplen = PAYPASSTRACK1DATAitem->len;

            track1panlen = 0;
			gEmvballocator.EMVBallocator_memset(track1pan,0,sizeof(track1pan));
			gEmvballocator.EMVBallocator_memset(track1expirydate,0,sizeof(track1expirydate));
            if(tmp[0] != 'B')
            {
                #ifdef EMVB_DEBUG
	            emvb_printf("\r\nDealPaypassAFLData9999\r\n");
				#endif
            	return ERR_EMV_IccDataFormat;
            }

			separator = 0;
			for(i = 1;i<tmplen;i++)
			{
				if(tmp[i] == 0x5E)
				{
				    if(separator == 0)
				    {
						if(i>20)
						{
						    #ifdef EMVB_DEBUG
				            emvb_printf("\r\nDealPaypassAFLDataaaaa\r\n");
							#endif
							return ERR_EMV_IccDataFormat;
						}
						separator = 1;
						gEmvballocator.EMVBallocator_memcpy(track1pan,&tmp[1],i-1);
						track1panlen = i-1;
				    }
					else
					{
					    separator = 2;
						EMVAscToBcd(track1expirydate,&tmp[i+1],4);
						break;
					}
				}
			}

			if(separator < 2)
			{
			    #ifdef EMVB_DEBUG
			            emvb_printf("\r\nDealPaypassAFLData888kkkjjj\r\n");
						#endif
				return ERR_EMV_IccDataFormat;
			}
			#ifdef EMVB_DEBUG
            emvb_printf("\r\ncheck track1 and track2 pan and expiry %d %d\r\n",track2panlen,track1panlen);
			for(i = 0;i<track2panlen;i++)
			{
				emvb_printf("%02x ",track2pan[i]);
			}
			emvb_printf("\r\n");
			for(i = 0;i<track1panlen;i++)
			{
				emvb_printf("%02x ",track1pan[i]);
			}
			emvb_printf("\r\n");
			emvb_printf("%02x %02x %02x %02x ",track2expirydate[0],track2expirydate[1],track1expirydate[0],track1expirydate[1]);
			emvb_printf("\r\n");
			#endif
			/*

			if((track2expirydate[0] < 1)||(track2expirydate[0] > 12))
			{
			    #ifdef EMVB_DEBUG
	            emvb_printf("\r\nDealPaypassAFLDatabbbb\r\n");
				#endif
				return ERR_EMV_IccDataFormat;
			}
			
			if((track1expirydate[1] < 1)||(track1expirydate[1] > 12))
			{
			    #ifdef EMVB_DEBUG
	            printfemv("\r\nDealPaypassAFLDatacccc\r\n");
				#endif
				return ERR_EMV_IccDataFormat;
			}
			*/

			if(memcmp(track2expirydate,track1expirydate,2))
			{
				#ifdef EMVB_DEBUG
	            emvb_printf("\r\nDealPaypassAFLDatadddd\r\n");
				#endif
				return ERR_EMV_IccDataFormat;
			}

			if((track1panlen == 0)||(track2panlen == 0)||(track1panlen != track2panlen))
			{
				#ifdef EMVB_DEBUG
	            emvb_printf("\r\nDealPaypassAFLDataeeee\r\n");
				#endif
				return ERR_EMV_IccDataFormat;
			}

			if(gEmvballocator.EMVBallocator_memcmp(track1pan,track2pan,track1panlen))
			{
				#ifdef EMVB_DEBUG
	            emvb_printf("\r\nDealPaypassAFLDataffff\r\n");
				#endif
				return ERR_EMV_IccDataFormat;
			}
			
		}
	}
	else   //M/CHIP
	{
		if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_AppExpireDate)==0 ||
			dllemvb_avl_checkiftagexist((unsigned char *)TAG_PAN)==0||
			dllemvb_avl_checkiftagexist((unsigned char *)TAG_CDOL1)==0)//||//(tempiccdatatable+MV_SDATagList)->bExist==0
		{
		    #ifdef EMVB_DEBUG
            emvb_printf("\r\nDealPaypassAFLDataicc1111\r\n");
			#endif
			return PAYPASS_CARDDATAMISSING;  //sxl20110311
		}

            if(tempApp_UnionStruct->EMVTradeParam->ODAstaus)
            {
                item = dllemvb_avl_gettagitempointerandexiststatus((unsigned char *)TAG_SDATagList,&TagbExist);
				
				if(TagbExist) //if SDA_TL exist
				{
					if((item->len==1) && (item->data[0]==0x82))
					{
					    gEmvballocator.EMVBallocator_memset(AIP,0,sizeof(AIP));
						dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AIP,AIP,0,2);
						gEmvballocator.EMVBallocator_memcpy((unsigned char*)&tempApp_UnionStruct->EMVTradeParam->AuthData[tempApp_UnionStruct->EMVTradeParam->AuthDataLen],AIP,2);
						tempApp_UnionStruct->EMVTradeParam->AuthDataLen += 2;
					}
					else
					{
					    #ifdef EMVB_DEBUG
			            emvb_printf("tempiccdatatable err1233 \r\n");
						#endif
					    return ERR_EMV_IccDataFormat;
					}
				}
				else
				{
				    return ERR_EMV_IccDataFormat;
				}
            }

			item = dllemvb_avl_gettagitempointerandexiststatus((unsigned char *)TAG_CVMList,&TagbExist);
			if(TagbExist) //if CVM_LIST exist//sxl 080704
			{
				if((item->len)%2 != 0)
				{
					#ifdef EMVB_DEBUG
		            emvb_printf("tempiccdatatable err2 \r\n");
					#endif
					return ERR_EMV_IccDataFormat;
				}
			}
			
			
	}
    
	return EMV_OK;
}

void Paypassb_Getdata_GetRecordIDSReadflag_check(EMVBAppUnionStruct *tempApp_UnionStruct)
{
	//S3R1.6
	//idsprocess ÒÑ¾­Ö´ÐÐ¹ý
	if(tempApp_UnionStruct->EMVTradeParam->paypassidsrunflag)
	{
		//S456.2 
		//Paypassb_AddTLVToList_RemoveTag((unsigned char *)TAG_PAYPSS_TAGSTOREADYET,(unsigned char *)TAG_PaypassDataToSend);
	    //S456.3
	    //if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_PaypassDataToSend)&&dllemvb_avl_checkiftagexist((unsigned char *)TAG_PAYPSS_TAGSTOREADYET)==0)
	    //{
			//S456.4
		//	Paypassb_SendDEKSignal(tempApp_UnionStruct,PAYPASSSTEP_S3_78,NULL);
	    //}
	}
	else
	{
		paypassb_idsprocess(tempApp_UnionStruct);
	}
	
}

void paypassb_tidydataneeded(void)
{
	EMVTAGCVLITEM *emvitem;
	unsigned short index = 0;
	unsigned char *tempbuf;
	unsigned int tempbufdatalen;
	unsigned char taglen;
	unsigned char tag[4];
	
	emvitem = dllemvb_avl_gettagitempointer((unsigned char *)TAG_PaypassDataNeeded);
	if(emvitem != NULL)
	{
		if(emvitem->len)
		{

			tempbufdatalen = 0;
			tempbuf = emvblib_malloc(emvitem->len);

			for(index = 0;index < emvitem->len;)
			{
			    gEmvballocator.EMVBallocator_memset(tag,0,sizeof(tag));
			    taglen = 0;
				tag[0] = emvitem->data[index];
				if((emvitem->data[index]&0x1f) == 0x1f)
				{
					taglen++;
					tag[1] = emvitem->data[index+1];
					if(emvitem->data[index+1]&0x80)
					{
					    tag[2] = emvitem->data[index+2];
						taglen++;
					}
					
				}
				taglen++;

               //tag not exist
			   if(dllemvb_avl_checkiftagexist(tag) == 0)
			   {
			   		gEmvballocator.EMVBallocator_memcpy(&tempbuf[tempbufdatalen],&emvitem->data[index],taglen);
					tempbufdatalen += taglen;
					
			   }

			   index += taglen;
				
			}

			if(tempbufdatalen != emvitem->len)
			{
				dllemvb_avl_createsettagvalue((unsigned char *)TAG_PaypassDataNeeded,tempbuf,tempbufdatalen);
			}

			emvblib_free(tempbuf);
			
		}
	}
	
}

void Paypassb_SaveSendAPDUData(APDU_SEND *ApduSend,EMVBAppUnionStruct *tempApp_UnionStruct)
{
	
    unsigned char *iccommand;
    unsigned short len = 0;
	
	iccommand = (unsigned char *)emvblib_malloc(300);
	
    gEmvballocator.EMVBallocator_memset(iccommand,0,300);
    gEmvballocator.EMVBallocator_memcpy(&iccommand[1],ApduSend->Command,4);
    len=len+5;
    ApduSend->Lc &=0x00ff;
    if(ApduSend->Lc>0)	//æœ‰å�‘é€�æ•°æ�?
    {
    	iccommand[5]=ApduSend->Lc;
        len=len+1;
        
        if(ApduSend->Lc>260) ApduSend->Lc = 260;
		gEmvballocator.EMVBallocator_memcpy(&iccommand[6],ApduSend->DataIn,ApduSend->Lc);

        len+=ApduSend->Lc;
        
    	if(ApduSend->Le>0)
    	{
			ApduSend->Le &=0x00ff;
	    	iccommand[6+ApduSend->Lc]=ApduSend->Le;
	    	len=len+1;
    	}
    }
    else
    {		
    	if(ApduSend->Le>0)
    	{
			ApduSend->Le &=0x00ff;
	    	iccommand[5+ApduSend->Lc]=ApduSend->Le;
	    	len=len+1;
    	}
    	else	//æ— è¿”å›žæ•°æ�?
    	{
    		len=len+1;
    		iccommand[5+ApduSend->Lc]=0;
    	}
    }    

    len -= 1;
    if(tempApp_UnionStruct->EMVTradeParam->Transactionloglen+4+len<(sizeof(tempApp_UnionStruct->EMVTradeParam->Transactionlog)))
	{
		tempApp_UnionStruct->EMVTradeParam->Transactionlog[tempApp_UnionStruct->EMVTradeParam->Transactionloglen++] = LOGTYPE_CAPDU;
		tempApp_UnionStruct->EMVTradeParam->Transactionlog[tempApp_UnionStruct->EMVTradeParam->Transactionloglen++] = LOGTYPE_STATUS_OK;
        tempApp_UnionStruct->EMVTradeParam->Transactionlog[tempApp_UnionStruct->EMVTradeParam->Transactionloglen++] = (unsigned char)(len>>8);
		tempApp_UnionStruct->EMVTradeParam->Transactionlog[tempApp_UnionStruct->EMVTradeParam->Transactionloglen++] = (unsigned char)(len);
		gEmvballocator.EMVBallocator_memcpy(&tempApp_UnionStruct->EMVTradeParam->Transactionlog[tempApp_UnionStruct->EMVTradeParam->Transactionloglen],&iccommand[1],len);
		tempApp_UnionStruct->EMVTradeParam->Transactionloglen += len;
		
	}
	
    emvblib_free(iccommand);
	
}

//20140222
unsigned char Paypassb_ReadAppData_OPS(EMVBAppUnionStruct *tempApp_UnionStruct)
{
	unsigned char retCode;
    EMVTAGCVLITEM *item;
    unsigned char aflexist = 0;
	unsigned char Read_AFL_Num = 0;
    unsigned char AFL_RecordNum = 0;
	unsigned char AFL_Num;
	APDU_SEND apdu_s;
	APDU_RESP apdu_r;
	unsigned char authdataflag;
	unsigned char AIP[2],TermCapab[3];
	unsigned char readrecordparseerr = 0;
	unsigned char cdol1processflag = 0,dsdolprocessflag = 0,udolprocessflag = 0;
	//unsigned char signedflag = 1;
	unsigned char proceddfirstwriteflag = 0;
	unsigned char Kernelconfig;
	//unsigned char readrecordflag = 0;
	unsigned char amount[6];
	unsigned char amountRTCL[6];
	//unsigned int tick;
	unsigned char KernelConfigure;
	unsigned char readrecordactive = 1;
	
    tempApp_UnionStruct->EMVTradeParam->AuthDataLen = 0;
    tempApp_UnionStruct->EMVTradeParam->bErrAuthData = 0;
	tempApp_UnionStruct->EMVTradeParam->bErrSDATL = 0;
	
	
	item = dllemvb_avl_gettagitempointer((unsigned char *)TAG_AFL);
    if(item != NULL)
    {
    	if(item->len>>2)
    	{
    		aflexist = 1;
    	}
    }
	
	if(aflexist == 0)
	{
		return PAYPASS_CARDDATAERR;
	}


	retCode = EMVB_CheckReadAFL(item);
	if(retCode != EMV_OK)
	{
		return PAYPASS_CARDDATAERR;
	}


	
    AFL_Num = item->len>>2;
	if(tempApp_UnionStruct->EMVTradeParam->qPBOCOrMSD == MSDTYPE)
	{
		if(gEmvballocator.EMVBallocator_memcmp(item->data,"\x08\x01\x01\x00",4) == 0)
		{
			AFL_Num = 1;
		}
	}
	else  //only emv mode not set
	{
	    //S3.30  S3.31
		if(gEmvballocator.EMVBallocator_memcmp(item->data,"\x08\x01\x01\x00",4) == 0)
		{
		    if((dllemvb_avl_gettagvalue((unsigned char *)TAG_KernelConfiguration)&0x80) == 0)
		    {
		        //S3.32
				Read_AFL_Num = 1;
		    }
		}

        //S3.60 RRP
        tempApp_UnionStruct->EMVTradeParam->rrpresponse = 1;
		retCode = Paypassb_RRP(tempApp_UnionStruct);
		if(retCode != EMV_OK)
		{
			return retCode;
		}
		tempApp_UnionStruct->EMVTradeParam->rrpresponse = 0;
		
	}
    
	if(Read_AFL_Num == AFL_Num)
	{
	    //S3R1.6
		return PAYPASS_CARDDATAERR;
	}

	
	
    
    //2017
    if(tempApp_UnionStruct->EMVTradeParam->qPBOCOrMSD == MSDTYPE)
    {
		//S3.76
		Paypassb_AddTLVToList_RemoveTag((unsigned char *)TAG_PAYPSS_TAGSTOREADYET,(unsigned char *)TAG_PaypassDataToSend);
	    //S3.77
	    if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_PaypassDataNeeded)||(dllemvb_avl_checkiftagexist((unsigned char *)TAG_PaypassDataToSend)&&dllemvb_avl_checkiftagempty((unsigned char *)TAG_PAYPSS_TAGSTOREADYET)))
	    {
			//S3.78 
	    	paypassb_SendDEKSignal(tempApp_UnionStruct,PAYPASSSTEP_S3_78,NULL);
	    }
    }
	else
	{
		paypassb_tidydataneeded();
		#ifdef ZTPAYPASS_DEBUG
		dllemvb_avl_printtagallvalue((unsigned char *)"dataneed1",(unsigned char *)TAG_PaypassDataNeeded);
		#endif
	}
	
	tempApp_UnionStruct->EMVTradeParam->paypassidsrunflag = 0;
    gEmvballocator.EMVBallocator_memset(tempApp_UnionStruct->EMVTradeParam->paypassgetdatatag,0,4);
	
		
	for(;Read_AFL_Num < AFL_Num&&readrecordactive;Read_AFL_Num++)
	{

		AFL_RecordNum = item->data[(Read_AFL_Num<<2) + 1];
        
		while((AFL_RecordNum <= item->data[(Read_AFL_Num<<2) + 2])&&readrecordactive)
		{
			//S3R1  £¬ÓÐget dataÒª´¦ÀíµÄÒªÏÈ´¦Àíget dataµÄ
			retCode = Paypassb_Getdata_BeforeReadRecord(tempApp_UnionStruct,readrecordparseerr);
		    if(retCode != EMV_OK)
		    {
		    	return retCode;
		    }
			
			Emvb_FormReadAflData(&apdu_s,AFL_RecordNum,item->data[(Read_AFL_Num<<2) + 0]);
			Paypassb_SaveSendAPDUData(&apdu_s,tempApp_UnionStruct);

			#ifdef ZTPAYPASS_DEBUG
			emvb_printf("read record:%x %x",AFL_RecordNum,item->data[(Read_AFL_Num<<2) + 0]);
			#endif
							
            if(tempApp_UnionStruct->EMVTradeParam->paypassidsrunflag)
			{
				if(tempApp_UnionStruct->EMVTradeParam->qPBOCOrMSD == qPBOCTYPE)
	            {
					//S4.28
					if(cdol1processflag == 0)
					{
						if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_CDOL1))
						{
						    #ifdef ZTPAYPASS_DEBUG
							emvb_printf("add CDOL to need");
			                dllemvb_avl_printtagallvalue((unsigned char *)"tagneed 1",(unsigned char *)TAG_PaypassDataNeeded);
							#endif
							//S4.29
							Paypassb_DOL_CheckAddToList((unsigned char *)TAG_CDOL1,(unsigned char *)TAG_PaypassDataNeeded);
							cdol1processflag = 1;
						}
					}
					
					//S4.30
					if(dsdolprocessflag == 0)
					{
						//S4.31
						if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_DSDOL))
						{
							if(dllemvb_avl_gettagvalue((unsigned char *)TAG_IDSStatus)&0x80)
							{
							    //S4.32
								if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_DSSlotManage))
								{
									if((dllemvb_avl_gettagvalue((unsigned char *)TAG_DSSlotManage)&0x10) == 0)
									{
										//S4.33
										Paypassb_DOL_CheckAddToList((unsigned char *)TAG_DSDOL,(unsigned char *)TAG_PaypassDataNeeded);
									}
									
								}
							}
							dsdolprocessflag = 1;
						}
						
					}


					//¼ì²éÊÇ·ñ»¹ÓÐrecordÒª¶Á,ÒÔ¼°ÏÂÌõÖ¸ÁîÊÇ get data
					//×îºóÒ»¸örecord record²»»áÖ´ÐÐ
					//if((Read_AFL_Num+1 < AFL_Num)||(AFL_RecordNum != item->data[(Read_AFL_Num<<2) + 2]) )
					{
		                //S456.2 
						Paypassb_AddTLVToList_RemoveTag((unsigned char *)TAG_PAYPSS_TAGSTOREADYET,(unsigned char *)TAG_PaypassDataToSend);
			            //S456.3
			           if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_PaypassDataToSend)&&dllemvb_avl_checkiftagexist((unsigned char *)TAG_PAYPSS_TAGSTOREADYET)==0)
			    	   {
							//S456.4
			        	   paypassb_SendDEKSignal(tempApp_UnionStruct,PAYPASSSTEP_S3_78,NULL);
			    		}
					}
					
				}
				else   // MSD
				{
					if(udolprocessflag == 0)
					{
						if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_qPBOCUndfinedParam))
						{
							//S7.14
							Paypassb_DOL_CheckAddToList((unsigned char *)TAG_qPBOCUndfinedParam,(unsigned char *)TAG_PaypassDataNeeded);
							cdol1processflag = 1;
						}
					}
					
				}
			}
			else
			{
				Paypassb_Getdata_GetRecordIDSReadflag_check(tempApp_UnionStruct);
			}
			
			tempApp_UnionStruct->EMVTradeParam->ifcmdsaved = 1;
			tempApp_UnionStruct->EMVB_qPBOCIccIsoCommand(&apdu_s,&apdu_r);
			tempApp_UnionStruct->EMVTradeParam->ifcmdsaved = 0;
			
			//readrecordflag = 1;
			if(tempApp_UnionStruct->EmvErrID->L3 == EMVB_ERRID_L3_STOP)
			{
				return ERR_APP_TIMEOUT;
			}
			if(readrecordparseerr)
            {
            	return PAYPASS_PARSEERR;
            }
		    if(apdu_r.ReadCardDataOk != EMV_OK)
		    {
		    	return ERR_APP_TIMEOUT;
		    }
            
			
			if(AFL_RecordNum<item->data[(Read_AFL_Num<<2) + 1]+item->data[(Read_AFL_Num<<2) + 3])
			{
				authdataflag = 1;
			}
            else
            {
            	authdataflag = 0;
            }
            
			
            retCode = Paypassb_ReadAFLRetData(tempApp_UnionStruct,&apdu_r,item->data[(Read_AFL_Num<<2) + 0],authdataflag);
            if(readrecordparseerr)
            {
            	return PAYPASS_PARSEERR;
            }
			
			if(retCode == PAYPASS_SW1SW2ERR)
            {
            	return retCode;
            }

			if(retCode != EMV_OK)
			{
			    if(readrecordparseerr == 0&&tempApp_UnionStruct->EMVTradeParam->qPBOCOrMSD == qPBOCTYPE)
			    {
			    	readrecordparseerr = 1;
			    }
				else
				{
					return PAYPASS_PARSEERR;
				}
			}

			KernelConfigure = dllemvb_avl_gettagvalue((unsigned char *)TAG_KernelConfiguration);
			//Read all records even when no CDA b3  S4.34
			if(tempApp_UnionStruct->EMVTradeParam->ODAstaus == 0 && ((KernelConfigure&0x04) == 0)&&tempApp_UnionStruct->EMVTradeParam->qPBOCOrMSD == qPBOCTYPE)
			{
			    //S4.37
			    if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_AppExpireDate)&&
			       dllemvb_avl_checkiftagexist((unsigned char *)TAG_PAN)&&
			       dllemvb_avl_checkiftagexist((unsigned char *)TAG_PANSeq)&&
			       dllemvb_avl_checkiftagexist((unsigned char *)TAG_AUC)&&
			       dllemvb_avl_checkiftagexist((unsigned char *)TAG_CVMList)&&
			       dllemvb_avl_checkiftagexist((unsigned char *)TAG_IACDefault)&&
			       dllemvb_avl_checkiftagexist((unsigned char *)TAG_IACDenial)&&
			       dllemvb_avl_checkiftagexist((unsigned char *)TAG_IACOnline)&&
			       dllemvb_avl_checkiftagexist((unsigned char *)TAG_IssuCountryCode)&&
			       dllemvb_avl_checkiftagexist((unsigned char *)TAG_Track2Equ)&&
			       dllemvb_avl_checkiftagexist((unsigned char *)TAG_CDOL1))
			    {
			        readrecordactive = 0;
			    }
			}
            
			//signedflag = 0;
			//process get data   
			AFL_RecordNum++;
			
		}
		
	}


	if(tempApp_UnionStruct->EMVTradeParam->qPBOCOrMSD == qPBOCTYPE)
    {
		//S4.28
		if(cdol1processflag == 0)
		{
			if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_CDOL1))
			{
			    #ifdef ZTPAYPASS_DEBUG
				emvb_printf("add CDOL to need");
                dllemvb_avl_printtagallvalue((unsigned char *)"tagneed 1",(unsigned char *)TAG_PaypassDataNeeded);
				#endif
				//S4.29
				Paypassb_DOL_CheckAddToList((unsigned char *)TAG_CDOL1,(unsigned char *)TAG_PaypassDataNeeded);
				cdol1processflag = 1;
			}
		}
		
		//S4.30
		if(dsdolprocessflag == 0)
		{
			//S4.31
			if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_DSDOL))
			{
				if(dllemvb_avl_gettagvalue((unsigned char *)TAG_IDSStatus)&0x80)
				{
				    //S4.32
					if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_DSSlotManage))
					{
						if((dllemvb_avl_gettagvalue((unsigned char *)TAG_DSSlotManage)&0x10) == 0)
						{
							//S4.33
							Paypassb_DOL_CheckAddToList((unsigned char *)TAG_DSDOL,(unsigned char *)TAG_PaypassDataNeeded);
						}
						
					}
				}
				dsdolprocessflag = 1;
			}
			
		}
		
	}
	else   // MSD
	{
		if(udolprocessflag == 0)
		{
			if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_qPBOCUndfinedParam))
			{
				//S7.14
				Paypassb_DOL_CheckAddToList((unsigned char *)TAG_qPBOCUndfinedParam,(unsigned char *)TAG_PaypassDataNeeded);
				cdol1processflag = 1;
			}
		}
		
	}
    
	
	
    //read recordºóÔÙ´¦ÀíÒ»´Îget data Ö¸Áî
	retCode = Paypassb_Getdata_BeforeReadRecord(tempApp_UnionStruct,readrecordparseerr);
    if(retCode != EMV_OK)
    {
    	return retCode;
    }
	
	//read record end
    if(readrecordparseerr)
    {
    	return PAYPASS_PARSEERR;
    }

	
	//delete data in data need
	//process det first
    #ifdef ZTPAYPASS_DEBUG
    dllemvb_avl_printtagallvalue((unsigned char *)"tagneed 2",(unsigned char *)TAG_PaypassDataNeeded);
	#endif
	
	paypassb_tidydataneeded();

	#ifdef ZTPAYPASS_DEBUG
    dllemvb_avl_printtagallvalue((unsigned char *)"tagneed 3",(unsigned char *)TAG_PaypassDataNeeded);
	#endif

	
	//if(tempApp_UnionStruct->EMVTradeParam->qPBOCOrMSD == qPBOCTYPE)
	{
		//S456.5  check process First Write Flag   //S78 A
		tempApp_UnionStruct->EMVTradeParam->rrpresponse = 1;
		//tick = tempApp_UnionStruct->user_gettimetick();
		while(1)
		{
		    item = dllemvb_avl_gettagitempointer((unsigned char *)TAG_ProfirstWF);
            if(item == NULL)
			{
				break;
			}
		
			if(item->len == 0) // tag empty
			{
				Paypassb_AddDataToList_T((unsigned char *)TAG_ProfirstWF,(unsigned char *)TAG_PaypassDataNeeded);
			}
			else
			{
				if(item->data[0] != 0x00)
				{
					proceddfirstwriteflag = 1;
				}
				
			}

			if(proceddfirstwriteflag == 0)
			{
				//S456.7   
				Paypassb_AddTLVToList_RemoveTag((unsigned char *)TAG_PAYPSS_TAGSTOREADYET,(unsigned char *)TAG_PaypassDataToSend);
	            //S456.8
				if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_PaypassDataNeeded)||(dllemvb_avl_checkiftagexist((unsigned char *)TAG_PaypassDataToSend)&&dllemvb_avl_checkiftagempty((unsigned char *)TAG_PAYPSS_TAGSTOREADYET)))
			    {
					//S6
					retCode = paypassb_SendDEKSignal(tempApp_UnionStruct,PAYPASSSTEP_S6,NULL);
			    }
				else
				{
					retCode = paypassb_SendDEKSignal(tempApp_UnionStruct,PAYPASSSTEP_S6_10,NULL);
				}
				if(retCode == qPBOC_RESETCOMMAND)
				{
					Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S2_4_0);
					return PAYPASS_ENDAPPLICATION;
				}
				else if(retCode != EMV_OK)
				{
					Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S2_3_0);
					return PAYPASS_ENDAPPLICATION;
				}
	            //×ßS6Á÷³Ì
	            //S6.8   //sxl?2017
	           Paypassb_Getdata_BeforeReadRecord(tempApp_UnionStruct,0);
				
			}
            else
            {
            	break;
            }
			
		}
		tempApp_UnionStruct->EMVTradeParam->rrpresponse = 0;
		
	}
	
    //S456.12
	if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_AmtAuthNum) == 0)
	{
		return ERR_EMV_IccDataFormat;
	}


	
    tempApp_UnionStruct->EMVTradeParam->rrpresponse = 1;
	gEmvballocator.EMVBallocator_memset(AIP,0,sizeof(AIP));
	dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AIP,AIP,0,2);
	Kernelconfig = dllemvb_avl_gettagvalue((unsigned char *)TAG_KernelConfiguration);


    gEmvballocator.EMVBallocator_memset(amount,0,sizeof(amount));
	gEmvballocator.EMVBallocator_memset(amountRTCL,0,sizeof(amountRTCL));
	dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AmtAuthNum,amount,0,6);
	if((AIP[0]&0x02) !=0&&(Kernelconfig&0x20))
	{
	   #ifdef EMVB_DEBUG
	   //emvb_printf("\r\ngPaypassProceFlag[aidindex].OndevCTLEF = %d\r\n",tempApp_UnionStruct->EMVTradeParam->gPaypassProceFlag[tempApp_UnionStruct->EMVTradeParam->gSelectedaidindex].OndevCTLEF);
	   #endif
	   dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_ondevRTCL,amountRTCL,0,6);
	   if(gEmvballocator.EMVBallocator_memcmp(amount,amountRTCL,6) > 0)	//³¬¹ý½»Ò×ÏÞ¶î£¬ÖØÐÂÑ¡Ôñ
	   {
		   Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S4_E15_0);
		   return EMV_APPSELECTTRYAGAIN;
	   }
	}
	else
	{
	   #ifdef EMVB_DEBUG
	   //emvb_printf("\r\ngPaypassProceFlag[aidindex].TermCTLEF = %d\r\n",tempApp_UnionStruct->EMVTradeParam->gPaypassProceFlag[tempApp_UnionStruct->EMVTradeParam->gSelectedaidindex].TermCTLEF);
	   #endif
	   
	   //if(tempApp_UnionStruct->EMVTradeParam->gPaypassProceFlag[tempApp_UnionStruct->EMVTradeParam->gSelectedaidindex].TermCTLEF)  //³¬¹ý½»Ò×ÏÞ¶î£¬ÖØÐÂÑ¡Ôñ
	   dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_clessofflineamt,amountRTCL,0,6);
	   if(gEmvballocator.EMVBallocator_memcmp(amount,amountRTCL,6) > 0)	//³¬¹ý½»Ò×ÏÞ¶î£¬ÖØÐÂÑ¡Ôñ
	   {
		   Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S4_E15_0);
		   return EMV_APPSELECTTRYAGAIN;
	   }
	   
	}


   #if 0 //sxl20171129
   if(tempApp_UnionStruct->EMVTradeParam->qPBOCOrMSD == qPBOCTYPE)
   {
		gEmvballocator.EMVBallocator_memset(TermCapab,0,sizeof(TermCapab));
		dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_TermCapab,TermCapab,0,3);
		#ifdef EMVB_DEBUG
		dllemvb_avl_printtagallvalue((unsigned char *)"init pre GPO TAG_TermCapab",(unsigned char *)TAG_TermCapab);
		#endif
 

	   if(tempApp_UnionStruct->EMVTradeParam->ContactlessCVMRLEF)  //ÐèÒª²âÊÔ
	   {
           #ifdef EMVB_DEBUG
		   emvb_printf("\r\ncvm required \r\n");
           #endif
		   
		   TermCapab[1] = dllemvb_avl_gettagvalue((unsigned char *)TAG_PAYPASSCVMRequired);
	   }
	   else
	   {
           #ifdef EMVB_DEBUG
		   emvb_printf("\r\n no cvm required \r\n");
           #endif
           TermCapab[1] = dllemvb_avl_gettagvalue((unsigned char *)TAG_PAYPASSNOCVMRequired);
		   
	   }

	   dllemvb_avl_createsettagvalue((unsigned char *)TAG_TermCapab,TermCapab,3);
   }
   #endif

   
   tempApp_UnionStruct->EMVTradeParam->rrpresponse = 0;
	
    //? S78.10
	retCode = DealPaypassbAFLData(tempApp_UnionStruct);
	if(retCode != EMV_OK)
	{
		return retCode;
	}

	if(tempApp_UnionStruct->EMVTradeParam->qPBOCOrMSD == qPBOCTYPE)
	{
	    retCode = paypassb_idsprocess_afterreadrecord(tempApp_UnionStruct);
	    if(retCode != EMV_OK)
	    {
	    	//S456.20
	    	//Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S6_20_1);
			//Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S6_20_2); 
			return ERR_EMV_IccDataFormat;
	    }
	}

	//S456.21  S78.12
	Paypassb_CheckPresent_AddTLVToList_RemoveTag((unsigned char *)TAG_PAYPSS_TAGSTOREADYET,(unsigned char *)TAG_PaypassDataToSend);
    //S456.22  S78.13
    if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_PaypassDataToSend))
    {
    	paypassb_SendDEKSignal(tempApp_UnionStruct,PAYPASSSTEP_S456_23,NULL);
    }


	
    //check floor limit  //sxl20171129
    dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_clessofflinelimitamt,amountRTCL,0,6);
	if(gEmvballocator.EMVBallocator_memcmp(amount,amountRTCL,6) > 0)
	{
		tempApp_UnionStruct->EMVTradeParam->ContactlessTermEFLEF = 1;
	}
    else
    {
    	tempApp_UnionStruct->EMVTradeParam->ContactlessTermEFLEF = 0;
    }


	dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_termcvm_limit,amountRTCL,0,6);
    if(gEmvballocator.EMVBallocator_memcmp(amount,amountRTCL,6) > 0)
	{
		tempApp_UnionStruct->EMVTradeParam->ContactlessCVMRLEF = 1;
	}
    else
    {
    	tempApp_UnionStruct->EMVTradeParam->ContactlessCVMRLEF = 0;
    }

	//check cvm limit
   if(tempApp_UnionStruct->EMVTradeParam->qPBOCOrMSD == qPBOCTYPE)
   {
       

		
		gEmvballocator.EMVBallocator_memset(TermCapab,0,sizeof(TermCapab));
		dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_TermCapab,TermCapab,0,3);
		#ifdef EMVB_DEBUG
		dllemvb_avl_printtagallvalue((unsigned char *)"init pre GPO TAG_TermCapab",(unsigned char *)TAG_TermCapab);
		#endif
 

	   if(tempApp_UnionStruct->EMVTradeParam->ContactlessCVMRLEF)  //ÐèÒª²âÊÔ
	   {
           #ifdef EMVB_DEBUG
		   emvb_printf("\r\ncvm required \r\n");
           #endif
		   //S456.31
		   tempApp_UnionStruct->pOutParameterSet->ReceiptinoutParameter = 1;
		   TermCapab[1] = dllemvb_avl_gettagvalue((unsigned char *)TAG_PAYPASSCVMRequired);
	   }
	   else
	   {
           #ifdef EMVB_DEBUG
		   emvb_printf("\r\n no cvm required \r\n");
           #endif
           TermCapab[1] = dllemvb_avl_gettagvalue((unsigned char *)TAG_PAYPASSNOCVMRequired);
		   
	   }

	   #ifdef EMVB_DEBUG
	   //API_TraceHex(DBG_APP_INFO," read record set TermCapab",TermCapab,3);
       #endif

	   dllemvb_avl_createsettagvalue((unsigned char *)TAG_TermCapab,TermCapab,3);
		
	   
   }
	
	return retCode;
	
}

/*******************************************************************
×÷    Õß: sxl
º¯ÊýÃû³Æ: unsigned char Paywave_ReadAppData(AppUnionStruct *tempApp_UnionStruct)
º¯Êý¹¦ÄÜ: ¶ÁÓ¦ÓÃÊý¾Ý
Èë¿Ú²ÎÊý: ÎÞ
·µ »Ø Öµ: ÎÞ
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:         20140222
********************************************************************/
unsigned char Paypassb_ReadAppData(EMVBAppUnionStruct *tempApp_UnionStruct)
{
	
    unsigned char retCode;

    
	tempApp_UnionStruct->EMVTradeParam->rrpresponse = 0;
	retCode = Paypassb_ReadAppData_OPS(tempApp_UnionStruct);
    if(tempApp_UnionStruct->EMVTradeParam->rrpresponse)
    {
    	
    	if(retCode != EMV_OK)
    	{
    		return retCode;
    	}
		
    }
	
	if(retCode == PAYPASS_CARDDATAERR)  
	{
		Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S3_E41_0);
		Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S3_90_1);
		Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S3_90_2);
	}
    else if(retCode == ERR_APP_TIMEOUT)
    {
        if(tempApp_UnionStruct->EmvErrID->L3 != EMVB_ERRID_L3_STOP)
        {
	    	Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S4_E4_0);      //S7.4
			Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S4_E5_0);      //S7.5
			Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S4_E6_0);
        }
    }
    else if(retCode == PAYPASS_SW1SW2ERR)
    {
    	Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S4_E10_1); 
		Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S4_E10_2);
    }
    else if(retCode == PAYPASS_PARSEERR)
    {
    	Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S4_E27_1);
		Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S4_E27_2); 
		
    }
	else if(retCode == PAYPASS_CARDDATAMISSING||retCode == ERR_EMV_IccDataMissing)
	{
		Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S5_E17_1);
		Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S5_E17_2);
		
	}
	else if(retCode != EMV_OK)
	{
		if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_AmtAuthNum) == 0)
		{
			Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S4_E13_0);
		}
		else
		{
			Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S5_E27_1);
			Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S5_E27_2); 
		}
	}
	
	return retCode;
}



/*******************************************************************
×÷    Õß:
º¯ÊýÃû³Æ: unsigned char Paypass_MSCheckCVM(AppUnionStruct *tempApp_UnionStruct)
º¯Êý¹¦ÄÜ: paypass MS check CVM
Èë¿Ú²ÎÊý:
·µ »Ø Öµ:
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:  20140222
********************************************************************/
unsigned char Paypassb_MSCheckCVM(EMVBAppUnionStruct *tempApp_UnionStruct)
{
	//unsigned char retCode;
    unsigned char AIP[2];
	unsigned char Kernelconfig;
	
	gEmvballocator.EMVBallocator_memset(AIP,0,sizeof(AIP));
    dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AIP,AIP,0,2);
	Kernelconfig = dllemvb_avl_gettagvalue((unsigned char *)TAG_KernelConfiguration);
        
		
		
	if((AIP[0]&0x02) !=0&&(Kernelconfig&0x20))
	{
		if(tempApp_UnionStruct->EMVTradeParam->ContactlessCVMRLEF == 1)   //   plaintext  PIN  Verification Performanced by ICC
		{
		    dllemvb_avl_setvalue_or((unsigned char *)TAG_MobileSupportIndicator,0,0x02);

		    Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S78_20_0);
			
		}
	}
    return EMV_OK;
	
}



/*******************************************************************
×÷    Õß:
º¯ÊýÃû³Æ: void Paypass_checkavn(AppUnionStruct *tempApp_UnionStruct)
º¯Êý¹¦ÄÜ:  check application version number
Èë¿Ú²ÎÊý: ÎÞ
·µ »Ø Öµ: ÎÞ
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:   20140222
********************************************************************/
void Paypassb_checkavn(EMVBAppUnionStruct *tempApp_UnionStruct)
{
    unsigned char AppVerbEixst;
    EMVTAGCVLITEM *AppVeritem = NULL;
    unsigned char TermAppVer[2];
	
	
	if(tempApp_UnionStruct->EMVTradeParam->qPBOCOrMSD == qPBOCTYPE)
	{
	    AppVeritem = dllemvb_avl_gettagitempointerandexiststatus((unsigned char *)TAG_AppVer,&AppVerbEixst);
		
		if(AppVerbEixst==0)//App version num is not exist,don't check it and continue following  process
			return;
        dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AppVerNum,TermAppVer,0,2);

		
        #ifdef EMVB_DEBUG
        emvb_printf("\r\ntempcardinfo->AppVer= %02x %02x %02x %02x \r\n",AppVeritem->data[0],AppVeritem->data[1],TermAppVer[0],TermAppVer[1]);
		#endif

		
		if(gEmvballocator.EMVBallocator_memcmp(AppVeritem->data,TermAppVer,2))
		{
			
		    #ifdef EMVB_DEBUG
            emvb_printf("\r\npaypass ICC version not compact\r\n");
			#endif

			dllemvb_avl_setvalue_or((unsigned char *)TAG_TVR,1,0x80);
		}
	}
	
}

/*******************************************************************
×÷    Õß:
º¯ÊýÃû³Æ: unsigned char Emv_FormDynSignGenerate(AppUnionStruct *tempApp_UnionStruct,APDU_SEND *apdu_s)
º¯Êý¹¦ÄÜ: ×éÖ¯DOLÊý¾Ý
Èë¿Ú²ÎÊý:
·µ »Ø Öµ:
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:     20140222
********************************************************************/
unsigned char Paypassb_DOLProcessFunc(unsigned char type,unsigned char* DOL,unsigned short DOLLen,unsigned char* DOLData,unsigned short* DOLDataLen, EMVBAppUnionStruct *tempApp_UnionStruct)
{
	
	unsigned short index = 0;
	unsigned char *buf;   //[255]
	unsigned char bInTable;
	unsigned char tag[4],taglen;
	EMVTAGCVLITEM *DOLdataitem;
	//EMVTAGCVLITEM emvtagitem;
	unsigned short templen,indexOut = 0;
	unsigned char bHasUnpredictNum = 0;
	unsigned char AIP[2],TermCapab[3];
	unsigned char k,m;
	//EMVTAGCVLITEM *lastDROLdataitem;
#ifdef EMVB_DEBUG
	unsigned char i;
#endif
	unsigned char lastdolflag = 0;
	
	gEmvballocator.EMVBallocator_memset(AIP,0,sizeof(AIP));
	dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AIP,AIP,0,2);
	gEmvballocator.EMVBallocator_memset(TermCapab,0,sizeof(TermCapab));
	dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_TermCapab,TermCapab,0,3);
	
 

	buf = (unsigned char *)emvblib_malloc(255);
	
	while(index<DOLLen)//Process PDOL
	{
		if(DOL[index]==0xFF || DOL[index]==0x00) {index++; continue;} 
		gEmvballocator.EMVBallocator_memset(buf,0,255);
		bInTable=0;


		gEmvballocator.EMVBallocator_memset(tag,0,sizeof(tag));
		taglen = 0;
		tag[taglen++] = DOL[index];
		if((tag[0]&0x1f) == 0x1f)
		{
			tag[taglen++] = DOL[index+1];
			if(tag[1]&0x80)
			{
				tag[taglen++] = DOL[index+2];
			}
		}

		if(index+taglen +1 >= DOLLen)
		{
			lastdolflag = 1;
		}
		
		
		DOLdataitem = dllemvb_avl_gettagitempointer(tag);
		
		
		if(DOLdataitem != NULL)
		{
			index += taglen;
			
			
			
			if(index+1>DOLLen)
			{
			    emvblib_free(buf);
				return ERR_EMV_IccDataFormat;
			}
			templen = DOL[index++];
			
			
			k = templen;   // 1
			m=DOLdataitem->len; // 4

			if(lastdolflag&&type == typeDSDOL)
			{
				if(k>DOLdataitem->len)
				{
					k = DOLdataitem->len;
				}
			}
			
			if(tempApp_UnionStruct->EMVTradeParam->qPBOCOrMSD == MSDTYPE)
			{
				if(gEmvballocator.EMVBallocator_memcmp(tag,"\x9F\x6A",2) == 0&&k)
				{
					if(m)
					{
						bHasUnpredictNum = 1;
					}
				}
			}
			else
			{
				if(gEmvballocator.EMVBallocator_memcmp(tag,"\x9F\x37",2) == 0&&k == 4)
				{
					if(m)
					{
						bHasUnpredictNum = 1;
					}
				}
			}

			
			
			if(DOLdataitem->datafomat&TAGFORMAT_N)//numeric
			{
				if(k>=m){
					if(m)
					{
						gEmvballocator.EMVBallocator_memcpy(&buf[k-m],DOLdataitem->data,m);
					}
					gEmvballocator.EMVBallocator_memcpy(&DOLData[indexOut],buf,k);
				}
				else{
					if(m)
					{
						gEmvballocator.EMVBallocator_memcpy(buf,DOLdataitem->data,m);
					}
					gEmvballocator.EMVBallocator_memcpy(&DOLData[indexOut],&buf[m-k],k);
				}
			}
			else if(DOLdataitem->datafomat&TAGFORMAT_CN)//compact numeric
			{
				if(m)
				{
					gEmvballocator.EMVBallocator_memset(buf,0xFF,255);
					gEmvballocator.EMVBallocator_memcpy(buf,DOLdataitem->data,m);
					gEmvballocator.EMVBallocator_memcpy(&DOLData[indexOut],buf,k);
				}
				else
				{
					gEmvballocator.EMVBallocator_memset(buf,0x00,255);
					gEmvballocator.EMVBallocator_memcpy(&DOLData[indexOut],buf,k);
				}
			}
			else//other formats
			{
				if(m)
				{
					gEmvballocator.EMVBallocator_memcpy(buf,DOLdataitem->data,m);
				}
				gEmvballocator.EMVBallocator_memcpy(&DOLData[indexOut],buf,k);
			}


			indexOut+=k;
			bInTable=1;
		}
		
		if(!bInTable)
		{
			index += taglen;
			if(index+1>DOLLen)
			{
			    emvblib_free(buf);
				return ERR_EMV_IccDataFormat;
			}
			templen = DOL[index++];

			if(lastdolflag&&type == typeDSDOL)
			{
				templen = 0;
			}
			k = templen;
			gEmvballocator.EMVBallocator_memcpy(&DOLData[indexOut],buf,k);
			indexOut+=k;
		}

		#ifdef EMVB_DEBUG
		emvb_printf("\r\nDOL tag:\r\n");
		for(i = 0;i < taglen;i++)
		{
			emvb_printf("%02x ",tag[i]);
		}
		emvb_printf("\r\n");
		#endif
	}

	emvblib_free(buf);

	if(bHasUnpredictNum == 0)
	{
		if(type == typeDDOL)
		{
			return EMV_ERR;
		}
		else if(type==typeCDOL1)
		{
			tempApp_UnionStruct->EMVTradeParam->bCDOL1HasNoUnpredictNum=1;	// 3MX6-9000  È¥µôreturn error
			//return EMV_ERR;
			//if((AIP[0]&0x01)&&(TermCapab[2]&0x08))
			//	return EMV_OK;
		}
		else if(type==typeCDOL2)
		{
			tempApp_UnionStruct->EMVTradeParam->bCDOL2HasNoUnpredictNum=1;
			if((AIP[0]&0x01)&&(TermCapab[2]&0x08))
				return EMV_OK;
		}
		else if(type != typeDSDOL)
		{
			return EMV_ERR;
		}
		
	}
	
	*DOLDataLen = indexOut;
	return EMV_OK;
	
}


/*******************************************************************
×÷    Õß:
º¯ÊýÃû³Æ: unsigned char Paypass_DOLProcess(AppUnionStruct *tempApp_UnionStruct,APDU_SEND *apdu_s)
º¯Êý¹¦ÄÜ: ×éÖ¯Êý¾Ý
Èë¿Ú²ÎÊý:
·µ »Ø Öµ:
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:   20140222
********************************************************************/
unsigned char Paypassb_DOLProcess(unsigned char type, unsigned char * DOL,unsigned short DOLLen,unsigned char* DOLData,unsigned short* DOLDataLen,EMVBAppUnionStruct *tempApp_UnionStruct)
{
	unsigned char retCode;
	
	retCode = Paypassb_DOLProcessFunc(type, DOL,DOLLen,DOLData,DOLDataLen,tempApp_UnionStruct);
	
	return retCode;
}



/*******************************************************************
×÷    Õß:
º¯ÊýÃû³Æ: unsigned char PayPass_CryptochecksumRetData(AppUnionStruct *tempApp_UnionStruct,APDU_RESP *apdu_r)
º¯Êý¹¦ÄÜ: ´¦ÀícryptochecksumÃüÁî·µ»ØµÄÊý¾Ý
Èë¿Ú²ÎÊý:
·µ »Ø Öµ:
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:  20140222
********************************************************************/
unsigned char PayPassb_CryptochecksumRetData(EMVBAppUnionStruct *tempApp_UnionStruct,APDU_RESP *apdu_r)
{
	unsigned short index,indexTemp,lenTemp;		//,cplen  len,,tmplen1
    unsigned char i;	//,k
	unsigned char *tmp,*tmpcarddata,tmppos,tmplen,startpos,cnt,startcount;  //[200]  [200]
	unsigned char bcdcvc3track2[24],bcdcvc3track1[24],*tmpbuf,bcdatc[24];  //[200]
	unsigned int  intcvc3track2,intcvc3track1,intatc;
	unsigned char qtrack2,j,tmpvalue,mtrack2,ktrack2,mtrack1,qtrack1,ktrack1;
	unsigned char qtrack2dexist,qtrack1dexist,separatorcnt;
	unsigned char *posbuf,posbuflen;   //[200]
	unsigned char *ddcarddata,ddcarddatalen;   //[200] 
	unsigned char tmpbuftrack[24];
    
	//unsigned char flag = 1;
	unsigned char ret;
	unsigned char bIntable;
	unsigned char PaypassCCCRespType;
	unsigned char AIP[2],Kernelconfig;
	unsigned char PaypassnUN1;
	unsigned char POSCII[3];
    EMVTAGCVLITEM *item;
	unsigned char PaypassCVC3Track2[2];
	unsigned char PaypassPcvc3Track2[2];
	unsigned char PaypassPunatcTrack2[2];
	unsigned char paypassun[4];
	unsigned char ATC[2];

	unsigned char PaypassCVC3Track1[2];
	unsigned char PaypassPCVC3Track1[6];
	unsigned char PaypassPunatcTrack1[6];

	unsigned char *mallocbuf;
    
	#ifdef EMVB_DEBUG
    emvb_printf("\r\nPayPass_CryptochecksumRetData \r\n");
	#endif

	mallocbuf = (unsigned char *)emvblib_malloc(1024);

	tmp = &mallocbuf[0];
	tmpcarddata = &mallocbuf[200];
    tmpbuf = &mallocbuf[400];
    posbuf = &mallocbuf[600];
	ddcarddata = &mallocbuf[800];

    index = 0;
	if(apdu_r->SWA==0x90 && apdu_r->SWB==0x00)
	{		
		if(apdu_r->DataOut[index]==0x77)//TLV coded data
		{
			index++;
			if(ParseExtLen(apdu_r->DataOut,&index,&lenTemp))
			{
			    emvblib_free(mallocbuf);
				return ERR_EMV_IccDataFormat;
			}

			#ifdef EMVB_DEBUG
            emvb_printf("\r\nindex = %d lentemp = %d\r\n",index,lenTemp);
			#endif

			indexTemp=index;
			while(index<indexTemp+lenTemp)
			{
			    #ifdef EMVB_DEBUG
                emvb_printf("\r\nindex = %d\r\n",index);
				#endif
				if(index>=apdu_r->LenOut) 
				{
				    emvblib_free(mallocbuf);
					return ERR_EMV_IccDataFormat;
				}
				if(apdu_r->DataOut[index]==0xFF || apdu_r->DataOut[index]==0x00) { index++; continue;}
                
				bIntable = 0;
				ret = Paypassb_ParseAndStoreCardResponse(tempApp_UnionStruct,apdu_r->DataOut,&index,&bIntable,2);
				if(ret != EMV_OK)
				{
				    emvblib_free(mallocbuf);
					return ret;
				}
			}
			if(index!=indexTemp+lenTemp)
			{
			    emvblib_free(mallocbuf);
				return ERR_EMV_IccDataFormat;
			}
			
		}
		else 
		{
		    emvblib_free(mallocbuf);
			return ERR_EMV_IccDataFormat;
		}
        
        if(index != apdu_r->LenOut)
        {
            emvblib_free(mallocbuf);
        	return ERR_EMV_IccDataFormat;
        }
        
		
		
	}
	else 
	{
	    emvblib_free(mallocbuf);
		return PAYPASS_SW1SW2ERR;
	}


    tempApp_UnionStruct->promptremovecardsoundled();   //20150612
    //Ö¸Ê¾µÆºÍÉùÒô´¦Àí¼´¿É
	Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S13_12_1);
	PaypassCCCRespType = 0;
	gEmvballocator.EMVBallocator_memset(AIP,0,sizeof(AIP));
    dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AIP,AIP,0,2);
	Kernelconfig = dllemvb_avl_gettagvalue((unsigned char *)TAG_KernelConfiguration);
    
	if((AIP[0]&0x02) !=0&&(Kernelconfig&0x20))
	{
		PaypassCCCRespType = 1;
	}
		


	if(PaypassCCCRespType == 0)  //CCC response-1
	{
        //S14.1
		if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_ATC) == 0)
		{
		    emvblib_free(mallocbuf);
			return PAYPASS_CARDDATAMISSING;
		}
        //S14.2   S14.3
        if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_POSCII) == 0 &&dllemvb_avl_checkiftagexist((unsigned char *)TAG_PaypassCVC3Track2)==0)
        {
            emvblib_free(mallocbuf);
			return PAYPASS_CARDDATAMISSING;//AIP or AFL missing.
        }
        //S14.5 S14.7
		if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_POSCII) &&dllemvb_avl_checkiftagexist((unsigned char *)TAG_PaypassCVC3Track2)==0)
		{
		    emvblib_free(mallocbuf);
			return PAYPASS_PHONECCCPCIIONLYE;
		}
		if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_POSCII) == 0 &&dllemvb_avl_checkiftagexist((unsigned char *)TAG_PaypassCVC3Track2))
		{
		    PaypassnUN1 = tempApp_UnionStruct->EMVTradeParam->PaypassnUN;
		}
		else
		{
		    //S14.6
		    PaypassnUN1 = tempApp_UnionStruct->EMVTradeParam->PaypassnUN;
			gEmvballocator.EMVBallocator_memset(POSCII,0,sizeof(POSCII));
			dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_POSCII,POSCII,0,3);
		    if(POSCII[1]&0x10)  //Offline PIN success
		    {
		    	//S14.8  
		    	PaypassnUN1 = (PaypassnUN1 + 5)%10;
		    }
		}
	}
	else   //CCC response-2
	{
		if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_POSCII) == 0 ||dllemvb_avl_checkiftagexist((unsigned char *)TAG_ATC) == 0)
		{
		    emvblib_free(mallocbuf);
			return PAYPASS_CARDDATAMISSING;//AIP or AFL missing.
		}

		if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_PaypassCVC3Track2) == 0)
		{
		    emvblib_free(mallocbuf);
			return PAYPASS_PHONECCCPCIIONLYE;
		}

		PaypassnUN1 = tempApp_UnionStruct->EMVTradeParam->PaypassnUN;
		gEmvballocator.EMVBallocator_memset(POSCII,0,sizeof(POSCII));
		dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_POSCII,POSCII,0,3);
	    if(POSCII[1]&0x10)  //Offline PIN success
	    {
	    	//S14.8  
	    	PaypassnUN1 = (PaypassnUN1 + 5)%10;
	    }
		else
		{
			if(tempApp_UnionStruct->EMVTradeParam->ContactlessCVMRLEF)
			{
			    emvblib_free(mallocbuf);
				return PAYPASS_CARDDATAERR;
			}
			*(tempApp_UnionStruct->paypassccctimes) = 0;
		}
		//flag = 0;
	}

    //S14.15
	if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_PayPassTrack1Data))
	{
		if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_PaypassCVC3Track1)==0)
		{
            //S14.16
		    emvblib_free(mallocbuf);
			return PAYPASS_CARDDATAMISSING;
		}
	}

    //×ª»¯¶þ´ÅµÀÊý¾Ý
	gEmvballocator.EMVBallocator_memset(tmp,0,200);
	item = dllemvb_avl_gettagitempointer((unsigned char *)TAG_PaypassMagTrack2);
    if(item==NULL)
    {
        emvblib_free(mallocbuf);
    	return PAYPASS_CARDDATAMISSING;
    }
	if(item->len == 0)
	{
	    emvblib_free(mallocbuf);
		return PAYPASS_CARDDATAMISSING;
	}
	
	EMVBcdToAsc(tmp,item->data,item->len);
	tmplen = (item->len)<<1;



    //tempterminfo->Paypassconverttrack2Len = 0;
	//memset(tempterminfo->Paypassconverttrack2,0,sizeof(tempterminfo->Paypassconverttrack2));

    #ifdef EMVB_DEBUG
    emvb_printf("\r\n transfer data\r\n");
	#endif
    qtrack2dexist = 0;
	for(i = 0;i<tmplen;i++)
	{
		if(tmp[i] == 'D')
		{
		    qtrack2dexist = 1;
			if(i>19)
			{
			    #ifdef EMVB_DEBUG
	            emvb_printf("\r\nPayPass_CryptochecksumRetData1111\r\n");
				#endif
	            emvblib_free(mallocbuf);
				return PAYPASS_CARDDATAERR;
			}

			if((tmp[tmplen-1] == 'F')||(tmp[tmplen-1] == 'f'))
			{
				if((i+8+1)>tmplen)
				{
					#ifdef EMVB_DEBUG
					emvb_printf("\r\nPayPass_CryptochecksumRetDat4444\r\n");
			        #endif
					emvblib_free(mallocbuf);
					return PAYPASS_CARDDATAERR;
				}
			}
			else
			{
				if((i+8)>tmplen)
				{
					#ifdef EMVB_DEBUG
					emvb_printf("\r\nPayPass_CryptochecksumRetDat5555\r\n");
			        #endif
					emvblib_free(mallocbuf);
					return PAYPASS_CARDDATAERR;
				}
			}
			gEmvballocator.EMVBallocator_memcpy(tmpcarddata,tmp,tmplen);
			tmppos = i+8;
			break;
		}
	}

	if(qtrack2dexist == 0)
	{
		#ifdef EMVB_DEBUG
		emvb_printf("\r\nPayPass_CryptochecksumRetData3333\r\n");
        #endif
		emvblib_free(mallocbuf);
		return PAYPASS_CARDDATAERR;
	}

	if((tmp[tmplen-1] == 'F')||(tmp[tmplen-1] == 'f'))
	{
		mtrack2 = tmplen-i-8-1;
	}
	else
	{
		mtrack2 = tmplen-i-8;
	}

	gEmvballocator.EMVBallocator_memcpy(ddcarddata,&tmp[tmppos],tmplen-tmppos);
	ddcarddatalen = tmplen-tmppos;
  
	#ifdef EMVB_DEBUG
    emvb_printf("\r\nmtrack2 = %d \r\n",mtrack2);
	#endif

    //binary encoded CVC3TRACK2 to the BCD encoding
    gEmvballocator.EMVBallocator_memset(PaypassCVC3Track2,0,sizeof(PaypassCVC3Track2));
	dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_PaypassCVC3Track2,PaypassCVC3Track2,0,2);
	intcvc3track2 = PaypassCVC3Track2[0];
    intcvc3track2 = (intcvc3track2<<8) + PaypassCVC3Track2[1];
    EMVU32ToBcd(bcdcvc3track2,intcvc3track2,8);
	gEmvballocator.EMVBallocator_memset(tmpbuf,0,200);
	EMVBcdToAsc(tmpbuf,bcdcvc3track2,8);

	#ifdef EMVB_DEBUG
    emvb_printf("\r\nbcdcvc3track2:\r\n");
    for(i= 0;i < 16;i++)
    {
    	emvb_printf("%02x ",tmpbuf[i]);
    }
	emvb_printf("\r\n");
	#endif
	startpos = 0;
	qtrack2 = 0;
	cnt = 0;
	startcount = 0;
	posbuflen = 0;
	gEmvballocator.EMVBallocator_memset(posbuf,0,200);

	gEmvballocator.EMVBallocator_memset(PaypassPcvc3Track2,0,sizeof(PaypassPcvc3Track2));
	dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_PaypassPcvc3Track2,PaypassPcvc3Track2,0,2);
	for(i = 0;i<2;i++)
	{
		tmpvalue = PaypassPcvc3Track2[i];
		for(j = 0;j<8;j++)
		{
		    if(startcount == 0)
		    {
				if((16-cnt) == mtrack2)
				{
				    startpos = cnt;
					startcount = 1;
				}
		    }
			if(tmpvalue&0x80)
			{
			    if(startcount)
			    {
					posbuf[posbuflen++] = tmppos+cnt-startpos;
					qtrack2++;
					#ifdef EMVB_DEBUG
       				emvb_printf("\r\nposbuf[posbuflen++]2 %d %02x",posbuflen-1,posbuf[posbuflen-1]);
		            #endif
			    }
			}
			tmpvalue = tmpvalue<<1;
			cnt++;
		}
	}

	#ifdef EMVB_DEBUG
    emvb_printf("\r\nqtrack2 = %d\r\n",qtrack2);
	#endif
	#if 0  //3C06-1000 
	if(qtrack2 < 3)
	{
    	#ifdef EMVB_DEBUG
		emvb_printf("\r\nPayPass_CryptochecksumRetData333a\r\n");
		#endif
		emvblib_free(mallocbuf);
		return PAYPASS_CARDDATAERR;
	}
	#endif
	//deal CVC3TRACK2
	//unusedpos = tmppos;
	for(i = 0;i<qtrack2;i++)
	{
		tmpcarddata[posbuf[i]] = tmpbuf[16+i-qtrack2];
		#ifdef EMVB_DEBUG
        emvb_printf("\r\ntmpcarddata[posbuf[i]] = %d %02x",posbuf[i],tmpcarddata[posbuf[i]]);
		#endif
		//unusedpos = posbuf[i];
	}

	//deal ATC and UN
    ktrack2 = 0;
	cnt = 0;
	startcount = 0;
	posbuflen = 0;
	gEmvballocator.EMVBallocator_memset(posbuf,0,200);
	gEmvballocator.EMVBallocator_memset(PaypassPunatcTrack2,0,sizeof(PaypassPunatcTrack2));
	dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_PaypassPunatcTrack2,PaypassPunatcTrack2,0,2);
	for(i = 0;i<2;i++)
	{
		tmpvalue = PaypassPunatcTrack2[i];
		for(j = 0;j<8;j++)
		{
		    if(startcount == 0)
		    {
				if((16-cnt) == mtrack2)
				{
				    startpos = cnt;
					startcount = 1;
				}
		    }
			if(tmpvalue&0x80)
			{
				if(startcount)
			    {
					posbuf[posbuflen++] = tmppos+cnt-startpos;
					ktrack2++;
					#ifdef EMVB_DEBUG
       				emvb_printf("\r\nposbuf[posbuflen++]1 %d %02x",posbuflen-1,posbuf[posbuflen-1]);
		            #endif
			    }
			}
			tmpvalue = tmpvalue<<1;
			cnt++;
		}
	}

	gEmvballocator.EMVBallocator_memset(tmpbuf,0,200);
	gEmvballocator.EMVBallocator_memset(tmpbuftrack,0,sizeof(tmpbuftrack));
	gEmvballocator.EMVBallocator_memset(paypassun,0,sizeof(paypassun));
	dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_paypassun,paypassun,0,4);
	gEmvballocator.EMVBallocator_memcpy(&tmpbuftrack[4],paypassun,4);
	EMVBcdToAsc(tmpbuf,tmpbuftrack,8);
	for(i = 0;i<(tempApp_UnionStruct->EMVTradeParam->PaypassnUN);i++)
	{
		tmpcarddata[posbuf[i+ktrack2-tempApp_UnionStruct->EMVTradeParam->PaypassnUN]] = tmpbuf[16+i-tempApp_UnionStruct->EMVTradeParam->PaypassnUN];
		#ifdef EMVB_DEBUG
        emvb_printf("\r\n111 %d %02x \r\n",posbuf[i+ktrack2-tempApp_UnionStruct->EMVTradeParam->PaypassnUN],tmpbuf[8+i-tempApp_UnionStruct->EMVTradeParam->PaypassnUN]);
		#endif
	}

    gEmvballocator.EMVBallocator_memset(ATC,0,sizeof(ATC));
	dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_ATC,ATC,0,2);
	intatc = ATC[0];
	intatc = (intatc << 8) + ATC[1];
	EMVU32ToBcd(bcdatc,intatc,8);
	gEmvballocator.EMVBallocator_memset(tmpbuf,0,200);
	EMVBcdToAsc(tmpbuf,bcdatc,8);

	
	
	for(i = 0;i<(ktrack2-tempApp_UnionStruct->EMVTradeParam->PaypassnUN);i++)
	{
		tmpcarddata[posbuf[i]] = tmpbuf[16+i-ktrack2+tempApp_UnionStruct->EMVTradeParam->PaypassnUN];
		#ifdef EMVB_DEBUG
        emvb_printf("\rn112 %d %02x \r\n",posbuf[i],tmpbuf[16+i-ktrack2+tempApp_UnionStruct->EMVTradeParam->PaypassnUN]);
		#endif
	}



	#ifdef EMVB_DEBUG
    emvb_printf("\r\ntempterminfo->PaypassnUN = %d %d\r\n",tempApp_UnionStruct->EMVTradeParam->PaypassnUN,tmppos+mtrack2-1);
	#endif
    
	tmpcarddata[tmppos+mtrack2-1] = PaypassnUN1 + 0x30;  //20130109
    
	//9f6B
	if(tmplen > 38)
	{
		tmplen = 38;
	}
	
	EMVAscToBcd(tmp,tmpcarddata,tmplen);
	dllemvb_avl_createsettagvalue((unsigned char *)TAG_PaypassMagTrack2,tmp,tmplen>>1);
    dllemvb_avl_createsettagvalue((unsigned char *)TAG_Paypassconverttrack2,ddcarddata,ddcarddatalen);
    
    
	//Èç¹ûÒ»´ÅµÀÊý¾Ý´æÔÚ£¬×ª»¯Ò»´ÅµÀÊý¾Ý
	if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_PayPassTrack1Data))
	{
		if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_PaypassCVC3Track1)==0) return ERR_EMV_IccDataMissing;//AIP or AFL missing.

        gEmvballocator.EMVBallocator_memset(tmp,0,200);

		item = dllemvb_avl_gettagitempointer((unsigned char *)TAG_PayPassTrack1Data);
	    if(item==NULL)
	    {
	        emvblib_free(mallocbuf);
	    	return PAYPASS_CARDDATAMISSING;
	    }
		if(item->len == 0)
		{
		    emvblib_free(mallocbuf);
			return PAYPASS_CARDDATAMISSING;
		}
	    
		gEmvballocator.EMVBallocator_memcpy(tmp,item->data,item->len);
		tmplen = item->len;
        
        
	    qtrack1dexist = 0;
		separatorcnt = 0;
		cnt = 0;
		for(i = 1;i<tmplen;i++)
		{
			if(tmp[i] == 0x5E)
			{
			    //qtrack2dexist = 1;
			    if(separatorcnt == 0)//PAN
			    {
					if(cnt>19)
					{
					    #ifdef EMVB_DEBUG
			            emvb_printf("\r\nPayPass_CryptochecksumRetData1111\r\n");
						#endif
			            emvblib_free(mallocbuf);
						return PAYPASS_CARDDATAERR;
					}
					separatorcnt = 1;
			    }
				else if(separatorcnt == 1)//name
				{
					if((cnt>26||cnt<2)&&cnt!=0)
					{
					    #ifdef EMVB_DEBUG
			            emvb_printf("\r\nPayPass_CryptochecksumRetData5555\r\n");
						#endif
			            emvblib_free(mallocbuf);
						return PAYPASS_CARDDATAERR;
					}

					if((i+8)>tmplen)
					{
						#ifdef EMVB_DEBUG
						emvb_printf("\r\nPayPass_CryptochecksumRetData6666\r\n");
				        #endif
						emvblib_free(mallocbuf);
						return PAYPASS_CARDDATAERR;
					}
					qtrack1dexist = 1;
                    gEmvballocator.EMVBallocator_memcpy(tmpcarddata,tmp,tmplen);
			        tmppos = i+8;
					break;
				}
				cnt = 0;
			}
			else
			{
				cnt++;
			}
		}

		if(qtrack1dexist == 0)
		{
			#ifdef EMVB_DEBUG
			emvb_printf("\r\nPayPass_CryptochecksumRetData333b\r\n");
	        #endif
			emvblib_free(mallocbuf);
			return PAYPASS_CARDDATAERR;
		}
		
		mtrack1 = tmplen-i-8;

		gEmvballocator.EMVBallocator_memcpy(ddcarddata,&tmp[tmppos],tmplen-tmppos);
	    ddcarddatalen = tmplen-tmppos;

		#ifdef EMVB_DEBUG
	    emvb_printf("\r\nmtrack1 = %d \r\n",mtrack1);
		#endif

	    //binary encoded CVC3TRACK2 to the BCD encoding
	    gEmvballocator.EMVBallocator_memset(PaypassCVC3Track1,0,sizeof(PaypassCVC3Track1));
		dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_PaypassCVC3Track1,PaypassCVC3Track1,0,2);
		intcvc3track1 = PaypassCVC3Track1[0];
	    intcvc3track1 = (intcvc3track1<<8) + PaypassCVC3Track1[1];
	    EMVU32ToBcd(bcdcvc3track1,intcvc3track1,24);
		gEmvballocator.EMVBallocator_memset(tmpbuf,0,200);
		EMVBcdToAsc(tmpbuf,bcdcvc3track1,24);
		
		qtrack1 = 0;
		cnt = 0;
		startcount = 0;
		posbuflen = 0;
		gEmvballocator.EMVBallocator_memset(posbuf,0,200);
		
		gEmvballocator.EMVBallocator_memset(PaypassPCVC3Track1,0,sizeof(PaypassPCVC3Track1));
		dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_PaypassPCVC3Track1,PaypassPCVC3Track1,0,6);
		for(i = 0;i<6;i++)
		{
			tmpvalue = PaypassPCVC3Track1[i];
			for(j = 0;j<8;j++)
			{
			    if(startcount == 0)
			    {
					if((48-cnt) == mtrack1)
					{
					    startpos = cnt;
						startcount = 1;
					}
			    }
				if(tmpvalue&0x80)
				{
				    if(startcount)
				    {
						posbuf[posbuflen++] = tmppos+cnt-startpos;
						qtrack1++;
				    }
				}
				tmpvalue = tmpvalue<<1;
				cnt++;
			}
		}

		#if 0  //3C06-1000 
		if(qtrack1 < 3)
		{
	    	#ifdef EMVB_DEBUG
			emvb_printf("\r\nPayPass_CryptochecksumRetData333f\r\n");
			#endif
			emvblib_free(mallocbuf);
			return PAYPASS_CARDDATAERR;
		}
		#endif
		
		//deal CVC3TRACK2
		#ifdef EMVB_DEBUG
        emvb_printf("\r\nqtrack1 %d\r\n",qtrack1);
		#endif
		for(i = 0;i<qtrack1;i++)
		{
			tmpcarddata[posbuf[i]] = tmpbuf[48+i-qtrack1];
			#ifdef EMVB_DEBUG
            emvb_printf("\r\nposbuf[i] %d %02x \r\n",posbuf[i],tmpcarddata[posbuf[i]]);
			#endif
		}

		//deal ATC and UN
	    ktrack1 = 0;
		cnt = 0;
		startcount = 0;
		posbuflen = 0;
		gEmvballocator.EMVBallocator_memset(posbuf,0,200);
		gEmvballocator.EMVBallocator_memset(PaypassPunatcTrack1,0,sizeof(PaypassPunatcTrack1));
		dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_PaypassPunatcTrack1,PaypassPunatcTrack1,0,6);
		for(i = 0;i<6;i++)
		{
			tmpvalue = PaypassPunatcTrack1[i];
			for(j = 0;j<8;j++)
			{
			    if(startcount == 0)
			    {
					if((48-cnt) == mtrack1)
					{
					    startpos = cnt;
						startcount = 1;
					}
			    }
				if(tmpvalue&0x80)
				{
					if(startcount)
				    {
						posbuf[posbuflen++] = tmppos+cnt-startpos;
						ktrack1++;
				    }
				}
				tmpvalue = tmpvalue<<1;
				cnt++;
			}
		}

		gEmvballocator.EMVBallocator_memset(tmpbuf,0,200);
		gEmvballocator.EMVBallocator_memset(tmpbuftrack,0,sizeof(tmpbuftrack));
		gEmvballocator.EMVBallocator_memcpy(&tmpbuftrack[20],paypassun,4);
		EMVBcdToAsc(tmpbuf,tmpbuftrack,24);
		for(i = 0;i<(tempApp_UnionStruct->EMVTradeParam->PaypassnUN);i++)
		{
			tmpcarddata[posbuf[i+ktrack1-tempApp_UnionStruct->EMVTradeParam->PaypassnUN]] = tmpbuf[48+i-tempApp_UnionStruct->EMVTradeParam->PaypassnUN];
			#ifdef EMVB_DEBUG
	        emvb_printf("\r\n113 %d %02x \r\n",posbuf[i+ktrack1-tempApp_UnionStruct->EMVTradeParam->PaypassnUN],tmpbuf[8+i-tempApp_UnionStruct->EMVTradeParam->PaypassnUN]);
			#endif
		}

		intatc = ATC[0];
		intatc = (intatc << 8) + ATC[1];
		EMVU32ToBcd(bcdatc,intatc,24);
		gEmvballocator.EMVBallocator_memset(tmpbuf,0,200);
		EMVBcdToAsc(tmpbuf,bcdatc,24);
		for(i = 0;i<(ktrack1-tempApp_UnionStruct->EMVTradeParam->PaypassnUN);i++)
		{
			tmpcarddata[posbuf[i]] = tmpbuf[48-ktrack1+tempApp_UnionStruct->EMVTradeParam->PaypassnUN+i];
			#ifdef EMVB_DEBUG
	        emvb_printf("\rn113 %d %02x \r\n",posbuf[i],tmpbuf[48-ktrack1+tempApp_UnionStruct->EMVTradeParam->PaypassnUN+i]);
			#endif
		}

	   
        
		tmpcarddata[tmppos+mtrack1-1] = PaypassnUN1 + 0x30;  //sxl20130109
        
        dllemvb_avl_createsettagvalue((unsigned char *)TAG_PayPassTrack1Data,tmpcarddata,tmplen);
        dllemvb_avl_createsettagvalue((unsigned char *)TAG_Paypassconverttrack1,ddcarddata,ddcarddatalen);
		
	}

	emvblib_free(mallocbuf);
	return EMV_OK;
}

//20140222
unsigned char Paypassb_phonemessagetrackdata(EMVBAppUnionStruct *tempApp_UnionStruct)
{
    
	//unsigned short index,indexTemp,len,lenTemp,tmplen1; 	//,cplen
	unsigned char i;	//,k
	unsigned char tmp[200],tmppos,tmplen,cnt; //startpos,,startcount  tmpcarddata[200],
	//unsigned char tmpbuf[200],bcdatc[24];//bcdcvc3track2[24],bcdcvc3track1[24],
	//unsigned int  intcvc3track2,intcvc3track1,intatc;
	//unsigned char mtrack2,mtrack1; //qtrack2,j,tmpvalue,ktrack2,,qtrack1,ktrack1
	unsigned char qtrack2dexist,qtrack1dexist,separatorcnt;
	//unsigned char posbuf[200],posbuflen;
	//unsigned char ddcarddata[200],ddcarddatalen;
	//unsigned char tmpbuftrack[24];

	//unsigned char flag = 1;
	//unsigned char ret;
	//unsigned char bIntable;
    EMVTAGCVLITEM *item;
	
    
	
	//×ª»¯¶þ´ÅµÀÊý¾Ý
	gEmvballocator.EMVBallocator_memset(tmp,0,sizeof(tmp));
	
	item = dllemvb_avl_gettagitempointer((unsigned char *)TAG_PaypassMagTrack2);
    if(item==NULL)
    {
    	return PAYPASS_CARDDATAMISSING;
    }
	if(item->len == 0)
	{
		return PAYPASS_CARDDATAMISSING;
	}
	
	EMVBcdToAsc(tmp,item->data,item->len);
	tmplen = (item->len)<<1;


    #ifdef EMVB_DEBUG
    emvb_printf("\r\n transfer data\r\n");
	#endif
    qtrack2dexist = 0;
	for(i = 0;i<tmplen;i++)
	{
		if(tmp[i] == 'D')
		{
		    qtrack2dexist = 1;
			if(i>19)
			{
			    #ifdef EMVB_DEBUG
	            emvb_printf("\r\nPayPass_CryptochecksumRetData1111\r\n");
				#endif
				return PAYPASS_CARDDATAERR;
			}

			if((tmp[tmplen-1] == 'F')||(tmp[tmplen-1] == 'f'))
			{
				if((i+8+1)>tmplen)
				{
					#ifdef EMVB_DEBUG
					emvb_printf("\r\nPayPass_CryptochecksumRetDat4444\r\n");
			        #endif
					return PAYPASS_CARDDATAERR;
				}
			}
			else
			{
				if((i+8)>tmplen)
				{
					#ifdef EMVB_DEBUG
					emvb_printf("\r\nPayPass_CryptochecksumRetDat5555\r\n");
			        #endif
					return PAYPASS_CARDDATAERR;
				}
			}
			//gEmvballocator.EMVBallocator_memcpy(tmpcarddata,tmp,tmplen);
			tmppos = i+8;
			break;
		}
	}

	
	if(qtrack2dexist == 0)
	{
		#ifdef EMVB_DEBUG
		emvb_printf("\r\nPayPass_CryptochecksumRetData3333\r\n");
        #endif
		return PAYPASS_CARDDATAERR;
	}
    /*
	if((tmp[tmplen-1] == 'F')||(tmp[tmplen-1] == 'f'))
	{
		mtrack2 = tmplen-i-8-1;
	}
	else
	{
		mtrack2 = tmplen-i-8;
	}
	*/

	//gEmvballocator.EMVBallocator_memcpy(ddcarddata,&tmp[tmppos],tmplen-tmppos);
	//ddcarddatalen = tmplen-tmppos;
    
    dllemvb_avl_createsettagvalue((unsigned char *)TAG_Paypassconverttrack2,&tmp[tmppos],tmplen-tmppos);

	
    



	//Èç¹ûÒ»´ÅµÀÊý¾Ý´æÔÚ£¬×ª»¯Ò»´ÅµÀÊý¾Ý
	if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_PayPassTrack1Data))
	{
        gEmvballocator.EMVBallocator_memset(tmp,0,sizeof(tmp));
		item = dllemvb_avl_gettagitempointer((unsigned char *)TAG_PayPassTrack1Data);
	    if(item==NULL)
	    {
	    	return PAYPASS_CARDDATAMISSING;
	    }
		if(item->len == 0)
		{
			return PAYPASS_CARDDATAMISSING;
		}
	
		gEmvballocator.EMVBallocator_memcpy(tmp,item->data,item->len);
		tmplen = item->len;
		

	    qtrack1dexist = 0;
		separatorcnt = 0;
		cnt = 0;
		for(i = 1;i<tmplen;i++)
		{
			if(tmp[i] == 0x5E)
			{
			    //qtrack2dexist = 1;
			    if(separatorcnt == 0)//PAN
			    {
					if(cnt>19)
					{
					    #ifdef EMVB_DEBUG
			            emvb_printf("\r\nPayPass_CryptochecksumRetData1111\r\n");
						#endif
						return PAYPASS_CARDDATAERR;
					}
					separatorcnt = 1;
			    }
				else if(separatorcnt == 1)//name
				{
					if((cnt>26||cnt<2)&&cnt!=0)
					{
					    #ifdef EMVB_DEBUG
			            emvb_printf("\r\nPayPass_CryptochecksumRetData5555\r\n");
						#endif
						return PAYPASS_CARDDATAERR;
					}

					if((i+8)>tmplen)
					{
						#ifdef EMVB_DEBUG
						emvb_printf("\r\nPayPass_CryptochecksumRetData6666\r\n");
				        #endif
						return PAYPASS_CARDDATAERR;
					}
					qtrack1dexist = 1;
                    //gEmvballocator.EMVBallocator_memcpy(tmpcarddata,tmp,tmplen);
			        tmppos = i+8;
					break;
				}
				cnt = 0;
			}
			else
			{
				cnt++;
			}
		}

		if(qtrack1dexist == 0)
		{
			#ifdef EMVB_DEBUG
			emvb_printf("\r\nPayPass_CryptochecksumRetData333b\r\n");
	        #endif
			return PAYPASS_CARDDATAERR;
		}
		
		//mtrack1 = tmplen-i-8;

		//gEmvballocator.EMVBallocator_memcpy(ddcarddata,&tmp[tmppos],tmplen-tmppos);
	    //ddcarddatalen = tmplen-tmppos;
		
        
        dllemvb_avl_createsettagvalue((unsigned char *)TAG_Paypassconverttrack1,&tmp[tmppos],tmplen-tmppos);
        
		
	}
	
	return EMV_OK;
}




//20140222
unsigned char paypassb_ccctimsdeal(EMVBAppUnionStruct *tempApp_UnionStruct)
{
    
	(*(tempApp_UnionStruct->paypassccctimes))++;
	if(*(tempApp_UnionStruct->paypassccctimes) >= MAXPAYPASSCCCTIMES)
	{
		*(tempApp_UnionStruct->paypassccctimes) = MAXPAYPASSCCCTIMES;
	}

	
	#ifdef EMVB_DEBUG
    emvb_printf("\r\npaypass_ccctimsdeal\r\n");
	#endif
	
    
	return PAYPASS_CCCWAITERR;
}





//20140222
unsigned char Paypassb_computecryptochecksum(EMVBAppUnionStruct *tempApp_UnionStruct)
{
    unsigned char paypassun[4];
    unsigned char tmp[8];
	unsigned char retCode;
	unsigned char *doldata;  //[255]
	unsigned short doldatalen;  //,len
	unsigned char *dol;   //[300]
	unsigned short dollen;
    EMVTAGCVLITEM *item;
    APDU_SEND apdu_s;
	APDU_RESP apdu_r;
	unsigned char needcccdelaytime = 0;
	unsigned char POSCII[3];
    PHONEMESSAGETABLEINFO *tempphonemsgtbl;
    unsigned char PaypassCCCRespType,AIP[2],Kernelconfig;
	unsigned char TermCapab[3];
	unsigned char j;
    
    
	tempphonemsgtbl = tempApp_UnionStruct->pphonemsgtable;
	dllemvb_avl_createsettagvalue((unsigned char *)TAG_CVMList,NULL,0);
	
    
    
	gEmvballocator.EMVBallocator_memset(paypassun,0,sizeof(paypassun));
	dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_paypassun,paypassun,0,4);
    EMVBcdToAsc(tmp,paypassun,4);
	gEmvballocator.EMVBallocator_memset(tmp,0x30,8-tempApp_UnionStruct->EMVTradeParam->PaypassnUN);
	EMVAscToBcd(paypassun,tmp,8);
    dllemvb_avl_createsettagvalue((unsigned char *)TAG_paypassun,paypassun,4);


	dol = (unsigned char *)emvblib_malloc(300);
	gEmvballocator.EMVBallocator_memset(dol,0,300);
	dollen = 0;

	item = dllemvb_avl_gettagitempointer((unsigned char *)TAG_qPBOCUndfinedParam);
	if(item != NULL)
	{
		if(item->len)
		{
			dollen = item->len;
		}
	}

    if(dollen == 0)
    {
    	item = dllemvb_avl_gettagitempointer((unsigned char *)TAG_TermUDOL);
		if(item != NULL)
		{
			if(item->len)
			{
				dollen = item->len;
			}
		}
    }

	if(dollen)
	{
		if(dollen > 255)
		{
			dollen = 255;
		}
		gEmvballocator.EMVBallocator_memcpy(dol,item->data,dollen);
	}
	else
	{
		dollen = 3;
		gEmvballocator.EMVBallocator_memcpy(dol,"\x9F\x6A\x04",3);
	}
    
    doldata = (unsigned char *)emvblib_malloc(255);
	gEmvballocator.EMVBallocator_memset(doldata,0,255);
    
	
	retCode = Paypassb_DOLProcess(typeDDOL,dol,dollen,doldata,&doldatalen,tempApp_UnionStruct);
	if(retCode != EMV_OK)
	{
	    #ifdef EMVB_DEBUG
		emvb_printf("\r\nretCodeer11 = %d\r\n",retCode);
		#endif

		emvblib_free(doldata);
		emvblib_free(dol);
		return retCode;
	}
	
    gEmvballocator.EMVBallocator_memcpy(apdu_s.Command,"\x80\x2A\x8E\x80",4); 
	apdu_s.Lc=doldatalen;
    gEmvballocator.EMVBallocator_memcpy((unsigned char*)&apdu_s.DataIn[0],doldata,doldatalen);
	apdu_s.Le=256;
	apdu_s.EnableCancel = 0;
    
    
	
	emvblib_free(doldata);
	emvblib_free(dol);
	
	
    tempApp_UnionStruct->EMVB_qPBOCIccIsoCommand(&apdu_s,&apdu_r);
    if(apdu_r.ReadCardDataOk != EMV_OK)
    {
        tempApp_UnionStruct->paypassdelay();
        paypassb_ccctimsdeal(tempApp_UnionStruct);
		needcccdelaytime = 1;
    	retCode = ERR_APP_TIMEOUT;
    }
	else
	{
		retCode = PayPassb_CryptochecksumRetData(tempApp_UnionStruct,&apdu_r);
		#ifdef EMVB_DEBUG
		emvb_printf("PayPass_CryptochecksumRetData retcode = %d\r\n",retCode);
		#endif
		
		if(retCode == PAYPASS_PHONECCCPCIIONLYE)
		{
		    retCode = Paypassb_phonemessagetrackdata(tempApp_UnionStruct);
			if(retCode != EMV_OK)
			{
				Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S14_21_1);
				tempApp_UnionStruct->paypassdelay();
				retCode = paypassb_ccctimsdeal(tempApp_UnionStruct);
				needcccdelaytime = 1;
				
			}
			else
			{
				gEmvballocator.EMVBallocator_memset(POSCII,0,sizeof(POSCII));
				dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_POSCII,POSCII,0,3);
				if((POSCII[1]&0x03)||(POSCII[2]&0x0F))  //S13.41
				{
				    //S13.44
				    for(j =0;j < tempphonemsgtbl->phonemessagetablenum;j++)
					{
						if((POSCII[0]&tempphonemsgtbl->phonemessagetable[j].PCIIMASK[0]) == tempphonemsgtbl->phonemessagetable[j].PCIIVALUE[0]&&
							(POSCII[1]&tempphonemsgtbl->phonemessagetable[j].PCIIMASK[1]) == tempphonemsgtbl->phonemessagetable[j].PCIIVALUE[1]&&
							(POSCII[2]&tempphonemsgtbl->phonemessagetable[j].PCIIMASK[2]) == tempphonemsgtbl->phonemessagetable[j].PCIIVALUE[2])  //messge id messege status 
						{
							tempApp_UnionStruct->EMVTradeParam->PaypassSelectedPOSCIIID = j;
							Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S13_44_0);
							break;
						}
					}
                    
					tempApp_UnionStruct->paypassdelay();

					(*(tempApp_UnionStruct->paypassccctimes))++;       //20150612 paypass modify
					if((*(tempApp_UnionStruct->paypassccctimes)) > 5)  
					{
						*(tempApp_UnionStruct->paypassccctimes) = 5;
					}
                    
					
					
					Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S13_45_0);
					retCode = PAYPASS_ENDAPPLICATION;
					
				}
				else//S13.42    //S14.22
				{
				    
					Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S13_42_0);
					
                    tempApp_UnionStruct->paypassdelay();
					
					(*(tempApp_UnionStruct->paypassccctimes))++;       //20150612 paypass modify
					if((*(tempApp_UnionStruct->paypassccctimes)) > 5)  
					{
						*(tempApp_UnionStruct->paypassccctimes) = 5;
					}
					
					Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S13_43_0);
					retCode = PAYPASS_DECLINED;
					
				}
			}
		}
        else if((retCode != EMV_OK) &&(retCode != PAYPASS_ENDAPPLICATION)&&(retCode != PAYPASS_DECLINED))
		{
		    
			if(retCode == PAYPASS_SW1SW2ERR)
			{
				Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S13_10_0);
			}
			else if(retCode == PAYPASS_CARDDATAMISSING)
		    {
		    	Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S13_14_4);
		    }
			else if(retCode == PAYPASS_CARDDATAERR)
			{
				Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S14_21_1);
			}
			else
			{
				Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S13_13_0);
			}
            
			tempApp_UnionStruct->paypassdelay();
			retCode = paypassb_ccctimsdeal(tempApp_UnionStruct);
			needcccdelaytime = 1;
			
		}
		else
		{
			*(tempApp_UnionStruct->paypassccctimes) = 0;
		}
        
		
		if(retCode == EMV_OK)
		{
		    
		    //Ö¸Ê¾µÆºÍÉùÒô´¦Àí¼´¿É

			PaypassCCCRespType = 0;
			gEmvballocator.EMVBallocator_memset(AIP,0,sizeof(AIP));
		    dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AIP,AIP,0,2);
			Kernelconfig = dllemvb_avl_gettagvalue((unsigned char *)TAG_KernelConfiguration);
		    
			if((AIP[0]&0x02) !=0&&(Kernelconfig&0x20))
			{
				PaypassCCCRespType = 1;
			}

			#ifdef EMVB_DEBUG
            emvb_printf("\r\nPaypassCCCRespType = %d %d\r\n",PaypassCCCRespType,tempApp_UnionStruct->EMVTradeParam->ContactlessCVMRLEF);
			#endif
            
			if(PaypassCCCRespType == 0)  //CCC response-1
			{
			    gEmvballocator.EMVBallocator_memset(TermCapab,0,sizeof(TermCapab));
				dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_TermCapab,TermCapab,0,3);
				if(tempApp_UnionStruct->EMVTradeParam->ContactlessCVMRLEF)  //CVM REQ
				{
				    TermCapab[1] = dllemvb_avl_gettagvalue((unsigned char *)TAG_magcvmrequirer); //CVM required  jiguang modify 20121220
                    dllemvb_avl_createsettagvalue((unsigned char *)TAG_TermCapab,TermCapab,3);
					Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S13_26_0);
				}
				else   //No CVM req
				{
				    TermCapab[1] = dllemvb_avl_gettagvalue((unsigned char *)TAG_magnocvmrequirer);
                    dllemvb_avl_createsettagvalue((unsigned char *)TAG_TermCapab,TermCapab,3);
					Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S13_25_0);
					
				}
			}
			else
			{
			    gEmvballocator.EMVBallocator_memset(POSCII,0,sizeof(POSCII));
				dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_POSCII,POSCII,0,3);
			    if(POSCII[1]&0x10)  
                {
                	Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S14_34_0);
                }
				else
				{
					Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S14_33_0);
				}
			}
		}
		
	}
    
    if(needcccdelaytime)
    {
    	//while(*(tempApp_UnionStruct->paypassccctimer))
    	//{
    		
    	//}

		if(retCode == ERR_APP_TIMEOUT)
		{
			Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S13_4_0);
			Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S13_5_0);
		}
        else
        {
        	Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S13_32_0);
			Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S13_33_0);
        }
		
    }
    
	
	return retCode;
    
}




//20140222
unsigned char Paypassb_CheckDataMissDDA(EMVBAppUnionStruct *tempApp_UnionStruct)
{
	unsigned char i;
    
    
	
	i = 0;
    
	while(1)
	{
		if(gEmvballocator.EMVBallocator_memcmp(PaypssCDAmandatoryTag[i].Tag,"\x00\x00\x00\x00",4) == 0)
		{
			break;
		}

		if(dllemvb_avl_checkiftagexist((unsigned char *)PaypssCDAmandatoryTag[i].Tag) == 0)
		{
			#ifdef EMVB_DEBUG
			emvb_printf("\nThere is DDA data missing");
			emvb_printf("\nMissing DDA data no: %d",i);
			#endif
			return ERR_EMV_IccDataMissing;
		}

		i++;
	}
    
    
	return EMV_OK;
}


//20140222
unsigned char Paypassb_DataAuth(EMVBAppUnionStruct *tempApp_UnionStruct)
{
    unsigned char retCode = EMV_OK;
	CAPK_STRUCT *tempcapk;
	
    if(tempApp_UnionStruct->EMVTradeParam->ODAstaus)  //need do CDA
    {
    	retCode = Paypassb_CheckDataMissDDA(tempApp_UnionStruct);
		if(retCode != EMV_OK)
		{
		     dllemvb_avl_setvalue_or((unsigned char *)TAG_TVR,0,0x24);
			 return EMV_OK;
		}
        
		tempcapk = tempApp_UnionStruct->EMVTradeParam->CAPK;
		if(tempcapk->ModulLen == 0 || tempApp_UnionStruct->EMVTradeParam->bErrAuthData)
		{
			dllemvb_avl_setvalue_or((unsigned char *)TAG_TVR,0,0x04);
		}
		
    }

    return EMV_OK;
}

//20140222
unsigned char  Paypassb_ReadBalanceRetData(APDU_RESP *apdu_r,unsigned char type)
{
    unsigned char index = 0,len;
	
	if(apdu_r->SWA==0x90 && apdu_r->SWB==0x00)//Get data OK
	{
		if(apdu_r->LenOut !=9) 
		{
			return ERR_EMV_IccDataFormat;
		}
		if(gEmvballocator.EMVBallocator_memcmp(apdu_r->DataOut,"\x9F\x50",2) == 0)
		{
		    index += 2;
            
		    len = apdu_r->DataOut[index++];

            if(len !=0 &&len !=6)
            {
            	return ERR_EMV_IccDataFormat;
            }
			
			if(len == 0)
			{
				return EMV_OK;
			}
            if((index+len) != apdu_r->LenOut)
            {
            	return ERR_EMV_IccDataFormat;
            }

			if(type == 0)
			{
				dllemvb_avl_createsettagvalue((unsigned char *)TAG_BalanceBeforeGAC,&apdu_r->DataOut[index],6);
			}
			else
			{
				dllemvb_avl_createsettagvalue((unsigned char *)TAG_BalanceAfterGAC,&apdu_r->DataOut[index],6);
			}
			
			return EMV_OK;
		}
		else 
		{
			return ERR_EMV_IccDataFormat;
		}
			
		
	}
	else
	{
		return ERR_EMV_IccDataFormat;
	}
	//return ERR_EMV_IccDataFormat;
}



//20140222
unsigned char Paypassb_preGenACBalanceRead(EMVBAppUnionStruct *tempApp_UnionStruct)
{
	unsigned char retCode = EMV_OK;
    APDU_SEND apdu_s;
	APDU_RESP apdu_r;
	unsigned char AppCapabilitiesInfor[3];
	EMVTAGCVLITEM *item;

	gEmvballocator.EMVBallocator_memset(AppCapabilitiesInfor,0,sizeof(AppCapabilitiesInfor));
	dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AppCapabilitiesInfor,AppCapabilitiesInfor,0,3);

    if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_BalanceBeforeGAC))
	{
		dllemvb_avl_createsettagvalue((unsigned char *)TAG_BalanceBeforeGAC,NULL,0);
	}
    item = dllemvb_avl_gettagitempointer((unsigned char *)TAG_BalanceBeforeGAC);
	
	if((AppCapabilitiesInfor[1]&0x02)&&(item!= NULL))
	{
		gEmvballocator.EMVBallocator_memset(&apdu_s,0,sizeof(APDU_SEND));
		gEmvballocator.EMVBallocator_memcpy(apdu_s.Command,"\x80\xCA\x9F\x50",4);
		apdu_s.Le = 0;
		apdu_s.EnableCancel = 1;
        tempApp_UnionStruct->EMVTradeParam->DisabelDET = 1;
        tempApp_UnionStruct->EMVB_qPBOCIccIsoCommand(&apdu_s,&apdu_r);
		tempApp_UnionStruct->EMVTradeParam->DisabelDET = 0;
    	if(apdu_r.ReadCardDataOk != EMV_OK)
    	{
    	    retCode = ERR_APP_TIMEOUT;
    		if(tempApp_UnionStruct->EmvErrID->L3 != EMVB_ERRID_L3_STOP)
    		{
    			Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S16_E1_0);
				Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S16_E2_0);
				Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S16_E3_0);
    		}
    	}
		else
		{
			Paypassb_ReadBalanceRetData(&apdu_r,0);
		}

		
	}

    
    return retCode;
	
}


/*******************************************************************
×÷    Õß:
º¯ÊýÃû³Æ: unsigned char Paypass_TermRiskManage(AppUnionStruct *tempApp_UnionStruct)
º¯Êý¹¦ÄÜ: Paypass ÖÕ¶Ë·çÏÕ¹ÜÀí
Èë¿Ú²ÎÊý:
·µ »Ø Öµ:
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:   20140222
********************************************************************/
unsigned char Paypassb_TermRiskManage(EMVBAppUnionStruct *tempApp_UnionStruct)
{

    //½»Ò×½ð¶î³¬ÏÞ
    #ifdef EMVB_DEBUG
    emvb_printf("\r\ntempterminfo->ContactlessTermEFLEF = %d\r\n",tempApp_UnionStruct->EMVTradeParam->ContactlessTermEFLEF);
	#endif
	if(tempApp_UnionStruct->EMVTradeParam->ContactlessTermEFLEF)
	{
		dllemvb_avl_setvalue_or((unsigned char *)TAG_TVR,3,0x80);//set 'transaction exceeds floor limit' bit 1.
	}
    
    
	
	if(tempApp_UnionStruct->EMVTradeParam->ContactlessCVMRLEF)
	{
		Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S5_E31_0);
	}
    
    
	return EMV_OK;
	
}

/*******************************************************************
×÷    Õß:
º¯ÊýÃû³Æ: unsigned char PaypassInitCardHolderVerify(AppUnionStruct *tempApp_UnionStruct)
º¯Êý¹¦ÄÜ: ³õÊ¼»¯³Ö¿¨ÈËÈÏÖ¤
Èë¿Ú²ÎÊý:
·µ »Ø Öµ:
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:  20140222
********************************************************************/
unsigned char PaypassbInitCardHolderVerify(EMVBAppUnionStruct *tempApp_UnionStruct,CVMSTRCUT *CVMdata)
{
	unsigned char i;
	unsigned char AIP[2],KernelConfigure;
	unsigned char CVMResult[3];
    unsigned char CVMListbExist;
	EMVTAGCVLITEM *CVMListitem = NULL;

	
	
    gEmvballocator.EMVBallocator_memset(AIP,0,sizeof(AIP));
    dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AIP,AIP,0,2);
	KernelConfigure = dllemvb_avl_gettagvalue((unsigned char *)TAG_KernelConfiguration);
    
	
	//CVM.1
	if((AIP[0]&0x02)&&(KernelConfigure&0x20))
	{
	    //CVM.2
		if(tempApp_UnionStruct->EMVTradeParam->ContactlessCVMRLEF == 1)   //   plaintext  PIN  Verification Performanced by ICC
		{
		    //CVM.4
		    Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_CVM_E4_0);
			CVMResult[0]=0x01;
			CVMResult[1]=0;
			CVMResult[2]=CVR_SUCCESS;
			dllemvb_avl_createsettagvalue((unsigned char *)TAG_CVMResult,CVMResult,3);
		}
		else
		{
		    //CVM.3
			CVMResult[0]=0x3f;
			CVMResult[1]=0;
			CVMResult[2]=CVR_SUCCESS;
			dllemvb_avl_createsettagvalue((unsigned char *)TAG_CVMResult,CVMResult,3);
			Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_CVM_E8_0);
			
		}
		return EMV_OK;
	}

    //CVM.5
	if(!(AIP[0]&0x10))   //¿¨²»Ö§³Ö³Ö¿¨ÈËÈÏÖ¤
	{
	    //CVM.6
		CVMResult[0]=0x3f;
		CVMResult[1]=0;
		CVMResult[2]=CVR_UNKNOWN;
		dllemvb_avl_createsettagvalue((unsigned char *)TAG_CVMResult,CVMResult,3);
        Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_CVM_E8_0);
		#ifdef EMVB_DEBUG
        emvb_printf("\r\nPaypassInitCardHolderVerify1\r\n");
		#endif
		return EMV_OK;
	}
	//CVM.7
	//get cvm list in the card, if not available, return
	CVMListitem = dllemvb_avl_gettagitempointerandexiststatus((unsigned char *)TAG_CVMList,&CVMListbExist);
	if(CVMListbExist==0x00)//CVM List is absent.
	{
        //CVM.8
		dllemvb_avl_setvalue_or((unsigned char *)TAG_TVR,0,0x20);
		CVMResult[0]=0x3f;
		CVMResult[1]=0;
		CVMResult[2]=CVR_UNKNOWN;
		dllemvb_avl_createsettagvalue((unsigned char *)TAG_CVMResult,CVMResult,3);
		Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_CVM_E8_0);
		#ifdef EMVB_DEBUG
        emvb_printf("\r\nPaypassInitCardHolderVerify2\r\n");
		#endif
		return EMV_OK;
	}
	
	if(CVMListitem->len<10||(CVMListitem->len%2))
	{
		dllemvb_avl_setvalue_or((unsigned char *)TAG_TVR,0,0x20);	//ICC Data Missing.sxl
		CVMResult[0]=0x3f;
		CVMResult[1]=0;
		CVMResult[2]=CVR_UNKNOWN;
		dllemvb_avl_createsettagvalue((unsigned char *)TAG_CVMResult,CVMResult,3);
		#ifdef EMVB_DEBUG
        emvb_printf("\r\nPaypassInitCardHolderVerify3\r\n");
		#endif
		Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_CVM_E8_0);
		return EMV_OK;
	}
	
	//to compatibal with PC and 51MCU and MCVZ328 MCU,make the long integer independent of byte order.
	gEmvballocator.EMVBallocator_memcpy(&CVMdata->CVM_X[2],CVMListitem->data,4);
	gEmvballocator.EMVBallocator_memcpy(&CVMdata->CVM_Y[2],&CVMListitem->data[4],4);

	
	CVMdata->CVRListLen=(CVMListitem->len-8)/2;
	for(i=0;i<CVMdata->CVRListLen;i++)//ºóÐøCVMÓÃÁíÍâ2×Ö½Ú
	{
		CVMdata->CVRList[i].method = CVMListitem->data[i*2+8];
		CVMdata->CVRList[i].condition = CVMListitem->data[i*2+9];
	}
	

	CVMResult[0]=0x3f;    //sxl ³õÊ¼»¯result
	CVMResult[1]=0;
	CVMResult[2]=CVR_FAIL;
	dllemvb_avl_createsettagvalue((unsigned char *)TAG_CVMResult,CVMResult,3);
    Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_CVM_E8_0);
	#ifdef EMVB_DEBUG
    emvb_printf("\r\nPaypassInitCardHolderVerify4\r\n");
	#endif
		
	return EMV_PARSESUC;
}


//20140222
unsigned char Paypassb_CheckIfSupportCVM(unsigned char method)   //20090202
{
    unsigned char temp;
	unsigned char TermCapab[3];
    
	
	temp = method&0x3F;

	gEmvballocator.EMVBallocator_memset(TermCapab,0,sizeof(TermCapab));
    dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_TermCapab,TermCapab,0,3);
	
	switch(temp)		//¸ù¾ÝCVMÀàÐÍ½øÐÐ²»Í¬µÄ´¦Àí.
	{
	case 0x00:	//ÈÏÎªCVMÊ§°Ü
		return 1;
		break;
	case 0x01://PLAINTEXT PIN VERIFICATION PERFORMED BY ICC
		return 0;  //not support
		/*
		if((TermCapab[1]&0x80)==0)
		{
			return 0;
		}
		else
		{
			return 1;
		}
		*/
		break;
	case 0x02://enciphered PIN verification online
		if((TermCapab[1]&0x40)==0)
		{
			return 0;
		}
		else
		{
			return 1;
		}
		break;
	case 0x03://Plaintext PIN verification performed by ICC and signature(paper)
	    return 0;
		/*
		if((TermCapab[1]&0xA0)!=0xA0)
		{
			return 0;
		}
		else
		{
			return 1;
		}
		*/
		break;
	case 0x04://enciphered PIN verification performed by ICC
		return 0;
		/*
		if((TermCapab[1]&0x10)==0)
		{
			return 0;
		}
		else
		{
			return 1;
		}
		*/
		break;
	case 0x05://enciphered PIN verification performed by ICC and signature(paper)
	    return 0;
		/*
		if((TermCapab[1]&0x30)!=0x30)
		{
			return 0;
		}
		else
		{
			return 1;
		}
		*/
		break;
	case 0x1E://signature (paper)
		if((TermCapab[1]&0x20)==0)
		{
			return 0;
		}
		else
		{
			return 1;
		}
		break;
	case 0x1F://no CVM required
		if((TermCapab[1]&0x08)==0)
		{					
			return 0;
		}
		else 
		{
			return 1;
		}
		break;
	default:
		return 0;
		break;
	}

	//return 0;
}


//20140222
unsigned char PaypassbAnalyCvmlist_cmpamount(unsigned char *CVMamount,unsigned char type)
{
    unsigned char TransCurcyCodebExist,TransCurcyCode[2];
    unsigned char TermAmtAuth[6],TermAmtCVM[6];
	unsigned char AppCurcyCodebExist,AppCurcyCode[2];
	unsigned int TermAmt;
    
	gEmvballocator.EMVBallocator_memset(TransCurcyCode,0,sizeof(TransCurcyCode));
    TransCurcyCodebExist = !(dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_TransCurcyCode,TransCurcyCode,0,2));
    
	gEmvballocator.EMVBallocator_memset(AppCurcyCode,0,sizeof(AppCurcyCode));
	AppCurcyCodebExist = !(dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AppCurcyCode,AppCurcyCode,0,2));
    
    gEmvballocator.EMVBallocator_memset(TermAmtAuth,0,sizeof(TermAmtAuth));    
	dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AmtAuthNum,TermAmtAuth,0,6);
    //EMVBcdToU32(&TermAmt,TermAmtAuth,6);
	//EMVIntToByteArray(TermAmt,TermAmtbin,4);    //ÊÇ·ñÐèÒªÏÞÖÆ½ð¶î,ÕâÀïÐèÒª½øÐÐÐÞ¸Ä paypassºÍpaywaveµÄÒ²Òª¼ì²é
    //×ª»»³É6¸ö×Ö½ÚÔÙ½øÐÐÅÐ¶Ï
	
	if(TransCurcyCodebExist==0x00 || AppCurcyCodebExist == 0)		//Application Currency Code is not present
	{
		return 0;
	}
    
	
	if( !gEmvballocator.EMVBallocator_memcmp(TransCurcyCode,AppCurcyCode,2))//under x shouldn't include case of equal x.(EMV2000 2CJ.077.02)
	{
		
		TermAmt = EMVByteArrayToInt(&CVMamount[2],4);
		gEmvballocator.EMVBallocator_memset(TermAmtCVM,0,sizeof(TermAmtCVM));
		EMVU32ToBcd(TermAmtCVM,TermAmt,6);
		
		if(type == 0)
		{
			if(gEmvballocator.EMVBallocator_memcmp(TermAmtAuth,TermAmtCVM,6) < 0)
			{
				return 1;
			}
		}
		else
		{
			if(gEmvballocator.EMVBallocator_memcmp(TermAmtAuth,TermAmtCVM,6) > 0)
			{
				return 1;
			}
		}
	}

	return 0;
}

/*******************************************************************
×÷    Õß:
º¯ÊýÃû³Æ: unsigned char AnalyCvmlist(unsigned char *needcvm,unsigned char *nextcvm,unsigned char CVRListLen,AppUnionStruct *tempApp_UnionStruct)
º¯Êý¹¦ÄÜ: CVMÁÐ±í·ÖÎö
Èë¿Ú²ÎÊý:
·µ »Ø Öµ:
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:   20140222
********************************************************************/
unsigned short PaypassbAnalyCvmlist(unsigned char method,unsigned char condition,unsigned char TransType,unsigned char TermType,unsigned char *CVM_X,unsigned char *CVM_Y)
{

	unsigned char needcvm = 0,nextcvm = 0;
	unsigned short returnvalue;
	unsigned char TermAmtOther[6];
    unsigned char TermAmtOthernotzero = 0;
	unsigned char ret;
	
	#ifdef EMVB_DEBUG
    emvb_printf("\r\n%02x %02x %02x \r\n",TermType,condition,method);
	#endif
    
	
	switch(condition)
	{
		case 0x00://always
			needcvm = 1;
			break;			
		case 0x01://if cash or cashback(EMV2000)£­> if unattended cash(modified in EMV4.1,SU16)
			if(TransType==CASH && (TermType & 0x0F) >3 )
			{
				needcvm = 1;
			}
			else nextcvm = 1;
			break;
		case 0x02://if not cash or cashback
		    gEmvballocator.EMVBallocator_memset(TermAmtOther,0,sizeof(TermAmtOther));
			dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AmtOtherNum,TermAmtOther,0,6);
			if(gEmvballocator.EMVBallocator_memcmp(TermAmtOther,"\x00\x00\x00\x00\x00\x00",6))
			{
				TermAmtOthernotzero = 1;
			}
			if(TransType!=CASH  && TransType!=CASHBACK&& TermAmtOthernotzero == 0)
			{
				needcvm = 1;					
			}
			else nextcvm = 1;
			break;
		case 0x03://if terminal support CVM   //sxl arm_linux
			//tempterminfo->needcvm = 1;
			 if(Paypassb_CheckIfSupportCVM(method))
			 {
			 	needcvm = 1;
			 }
			 else
			 {
			 	nextcvm = 1;
			 }
			break;
		case 0x04://if manual cash (added in EMV4.1,SU16)  //cash²Î¿¼EMVÎÄµµ
			if(TransType==CASH && (TermType & 0x0F) <= 3 )
			{
				needcvm = 1;
			}
			else nextcvm = 1;
			break;
		case 0x05://if purchase with cashback (added in EMV4.1,SU16)
		    gEmvballocator.EMVBallocator_memset(TermAmtOther,0,sizeof(TermAmtOther));
			dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AmtOtherNum,TermAmtOther,0,6);
			if(gEmvballocator.EMVBallocator_memcmp(TermAmtOther,"\x00\x00\x00\x00\x00\x00",6))
			{
				TermAmtOthernotzero = 1;
			}
			if(TransType==CASHBACK|| TermAmtOthernotzero )
			{
				needcvm = 1;
			}
			else nextcvm = 1;
			break;
		
		case 0x06://if trans is in App currency and under X value
		    ret  = PaypassbAnalyCvmlist_cmpamount(CVM_X,0);
			if(ret == 0)
			{
				nextcvm = 1;
			}
			else
			{
				needcvm = 1;
			}
			
			break;
		case 0x07://if trans is in App currency and over X value
		    ret  = PaypassbAnalyCvmlist_cmpamount(CVM_X,1);
			if(ret == 0)
			{
				nextcvm = 1;
			}
			else
			{
				needcvm = 1;
			}
			
			break;
		case 0x08://if trans is in App currency and under Y value
			ret  = PaypassbAnalyCvmlist_cmpamount(CVM_Y,0);
			if(ret == 0)
			{
				nextcvm = 1;
			}
			else
			{
				needcvm = 1;
			}
			break;
		case 0x09://if trans is in App currency and over Y value
			ret  = PaypassbAnalyCvmlist_cmpamount(CVM_Y,1);
			if(ret == 0)
			{
				nextcvm = 1;
			}
			else
			{
				needcvm = 1;
			}
			break;
		default:
			nextcvm = 1;
			break;
	}

    returnvalue = nextcvm;
    returnvalue = (returnvalue<<8)|needcvm;
	
	return returnvalue;
}

/*******************************************************************
×÷    Õß:
º¯ÊýÃû³Æ: unsigned char Paypass_PerformCVM(AppUnionStruct *tempApp_UnionStruct)
º¯Êý¹¦ÄÜ: ³Ö¿¨ÈËÈÏÖ¤
Èë¿Ú²ÎÊý:
·µ »Ø Öµ:
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:   20140222
********************************************************************/
unsigned char Paypassb_PerformCVM(EMVBAppUnionStruct *tempApp_UnionStruct,unsigned char method,unsigned char condition,unsigned char *TermCapab)
{
	unsigned char retCode = 0;
	unsigned char temp;
	unsigned char CVMResult[3];
	
	
	temp = method&0x3F;
    
    
	
	switch(temp)		//¸ù¾ÝCVMÀàÐÍ½øÐÐ²»Í¬µÄ´¦Àí.
	{
		case 0x00:	   //ÈÏÎªCVMÊ§°Ü
		    if((method&0x40) == 0)
		    {
				CVMResult[2]=CVR_FAIL;
				retCode=ERR_EMV_CVRFailALWAYS;
		    }
			else
			{
				retCode=ERR_EMV_CVRFail;
			}
			break;
		case 0x01:    //PLAINTEXT PIN VERIFICATION PERFORMED BY ICC
			return ERR_EMV_CVRNoSupport;
            break;
		case 0x02:   //enciphered PIN verification online
			if((TermCapab[1]&0x40)==0)//sxl
			{
				return ERR_EMV_CVRNoSupport;
			}
			Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_CVM_E18_1);
			CVMResult[2]=CVR_UNKNOWN;
			tempApp_UnionStruct->EMVTradeParam->cvmonlinepinreq = 1;
			dllemvb_avl_setvalue_or((unsigned char *)TAG_TVR,2,0x04);  //ÃÜÂëÔÚ×îºóÊäÈë£¬Ò»¶¨ÒªÏÈÖÃÆðÀ´±êÖ¾
			retCode = EMV_OK;
			break;
		case 0x03:  //Plaintext PIN verification performed by ICC and signature(paper)
		    return ERR_EMV_CVRNoSupport;
			break;
		case 0x04:  //enciphered PIN verification performed by ICC
			return ERR_EMV_CVRNoSupport;
			break;
		case 0x05: //enciphered PIN verification performed by ICC and signature(paper)
			return ERR_EMV_CVRNoSupport;
			break;
		case 0x1E://signature (paper)
			#ifdef EMVB_DEBUG
			emvb_printf("\n\r Come to 1E,Sign paper %02x\n\r",TermCapab[1]);
			#endif 
			if((TermCapab[1]&0x20)==0)  //sxl EMV4.1e
			{
				return ERR_EMV_CVRNoSupport;
				//break;
			}
			//Emv_Signature(temp,Num,tempApp_UnionStruct);	
			Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_CVM_E18_0);
			tempApp_UnionStruct->EMVTradeParam->bPrintReceipt=1;
			CVMResult[2]=CVR_UNKNOWN;
			retCode=EMV_OK;
			break;
		case 0x1F://no CVM required
			#ifdef EMVB_DEBUG
			emvb_printf("\n\r Come to 1F,No cvm required \n\r");
			emvb_printf("\n\r TermCapab[1] =%02x\n\r",TermCapab[1]);
			#endif 
			
			if((TermCapab[1]&0x08)==0)   //sxl EMV4.1E
			{
			     return ERR_EMV_CVRNoSupport;
				//tempterminfo->CVMResult[2]=CVR_FAIL;
				//retCode= ERR_EMV_CVRNoSupport;
				//break;
			}
			dllemvb_avl_setvalue_and((unsigned char *)TAG_TVR,2,0x7F);
			CVMResult[2]=CVR_SUCCESS;
			retCode=EMV_OK;

			break;	
		default:
			dllemvb_avl_setvalue_or((unsigned char *)TAG_TVR,2,0x40);
			CVMResult[2]=CVR_FAIL;//sxl
			return ERR_EMV_CVRFail;
			break;
		
	}
	CVMResult[0]=method;
	CVMResult[1]=condition;

	dllemvb_avl_createsettagvalue((unsigned char *)TAG_CVMResult,CVMResult,3);
	
	return retCode;
}

/*******************************************************************
×÷    Õß:
º¯ÊýÃû³Æ: unsigned char Paypass_CardHolderVerf(AppUnionStruct *tempApp_UnionStruct)
º¯Êý¹¦ÄÜ: ³Ö¿¨ÈËÈÏÖ¤
Èë¿Ú²ÎÊý:
·µ »Ø Öµ:
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:   20140222
********************************************************************/
unsigned char Paypassb_CardHolderVerf(EMVBAppUnionStruct *tempApp_UnionStruct)
{
	unsigned char retCode;
    CVMSTRCUT CVMdata;
	unsigned char NowCVRListLen = 0;
	unsigned char needcvm,nextcvm;
	unsigned short needcvmnextcvm;
	unsigned char TransType,TermType;
	unsigned char TermCapab[3];
	unsigned char CVMResult[3];
    
	tempApp_UnionStruct->EMVTradeParam->cvmonlinepinreq = 0;
    
	gEmvballocator.EMVBallocator_memset(&CVMdata,0,sizeof(CVMSTRCUT));
	retCode = PaypassbInitCardHolderVerify(tempApp_UnionStruct,&CVMdata);
    if(retCode == EMV_OK)
    {
    	return EMV_OK;
    }
    
	
	TransType = tempApp_UnionStruct->EMVTradeParam->TransType;
    TermType = dllemvb_avl_gettagvalue((unsigned char *)TAG_TermType);

    gEmvballocator.EMVBallocator_memset(TermCapab,0,sizeof(TermCapab));
	dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_TermCapab,TermCapab,0,3);

	#ifdef EMVB_DEBUG
    dllemvb_avl_printtagallvalue((unsigned char *)"CVM TAG_TermCapab:",(unsigned char *)TAG_TermCapab);
	emvb_printf("\r\nCVM trans type = %d\r\n",tempApp_UnionStruct->EMVTradeParam->TransType);
	#endif
	
	
	while(NowCVRListLen < CVMdata.CVRListLen)
	{

		needcvmnextcvm = 0;
		needcvmnextcvm = PaypassbAnalyCvmlist(CVMdata.CVRList[NowCVRListLen].method,CVMdata.CVRList[NowCVRListLen].condition,TransType,TermType,CVMdata.CVM_X,CVMdata.CVM_Y);
        
		
        needcvm = needcvmnextcvm&0xff;
        nextcvm = (needcvmnextcvm>>8)&0xff;
		
		if(needcvm == 1)
		{
			retCode=Paypassb_PerformCVM(tempApp_UnionStruct,CVMdata.CVRList[NowCVRListLen].method,CVMdata.CVRList[NowCVRListLen].condition,TermCapab);

            #ifdef EMVB_DEBUG
            emvb_printf("\r\n Paypass_PerformCVM retCode = %02x \r\n",retCode);
			#endif
			
			if(retCode==EMV_OK)
			{
				return retCode;
			}
			
			
            #ifdef EMVB_DEBUG
            emvb_printf("\r\ntempterminfo->CVRList[tempterminfo->NowCVRListLen].method =%02x %d\r\n",CVMdata.CVRList[NowCVRListLen].method,retCode);
			#endif
			if(retCode == ERR_EMV_CVRFailALWAYS)
			{
				dllemvb_avl_setvalue_or((unsigned char *)TAG_TVR,2,0x80);

				if((CVMdata.CVRList[NowCVRListLen].method&0x3f) == 0)
				{
					CVMResult[0]=CVMdata.CVRList[NowCVRListLen].method;
					CVMResult[1]=CVMdata.CVRList[NowCVRListLen].condition;
					CVMResult[2] = 0x01;

					dllemvb_avl_createsettagvalue((unsigned char *)TAG_CVMResult,CVMResult,3);
				}
				return EMV_OK;
			}
			
			if(((CVMdata.CVRList[NowCVRListLen].method & 0x40)==0x00) || (NowCVRListLen==CVMdata.CVRListLen-1))
			{
				dllemvb_avl_setvalue_or((unsigned char *)TAG_TVR,2,0x80);
				if((CVMdata.CVRList[NowCVRListLen].method&0x3f) == 0)
				{
					CVMResult[0]=CVMdata.CVRList[NowCVRListLen].method;
					CVMResult[1]=CVMdata.CVRList[NowCVRListLen].condition;
					CVMResult[2] = 0x01;

					dllemvb_avl_createsettagvalue((unsigned char *)TAG_CVMResult,CVMResult,3);
				}
				return EMV_OK;
			}
			else nextcvm = 1;
			
		}
		if(nextcvm == 1)
		{
			(NowCVRListLen)++;

		}
	}
	dllemvb_avl_setvalue_or((unsigned char *)TAG_TVR,2,0x80);			//set "Cardholder verification was not successful"
	return EMV_OK;
}


//20140222
unsigned char Paypassb_TermActAnaly(EMVBAppUnionStruct *tempApp_UnionStruct)
{
	unsigned char i,k;//TermAnaResult,CardAnaResult;//0-Denial,1-Online,2-Offline
	//unsigned char bFitIAC,bFitTAC;
	//Card_TAC CardTAC;
    unsigned char TVR[5];
	unsigned char TACDenial[5];
	unsigned char IACDenial[5],IACDenialbExist;
	unsigned char TermType;
	unsigned char TACOnline[5],IACOnline[5],IACOnlinebExist,TACOnlineOrValue[5];
	unsigned char TACDefault[5],IACDefault[5],IACDefaultbExist;
    
	#ifdef EMVB_DEBUG
	dllemvb_avl_printtagallvalue((unsigned char *)"TVR",(unsigned char *)TAG_TVR);
	dllemvb_avl_printtagallvalue((unsigned char *)"Term online",(unsigned char *)TAG_TACOnline);
	dllemvb_avl_printtagallvalue((unsigned char *)"Term default",(unsigned char *)TAG_TACDefault);
    dllemvb_avl_printtagallvalue((unsigned char *)"Term declined",(unsigned char *)TAG_TACDenial);
    dllemvb_avl_printtagallvalue((unsigned char *)"ICC online",(unsigned char *)TAG_IACOnline);
	dllemvb_avl_printtagallvalue((unsigned char *)"ICC default",(unsigned char *)TAG_IACDefault);
    dllemvb_avl_printtagallvalue((unsigned char *)"ICC declined",(unsigned char *)TAG_IACDenial);
	#endif
    
    gEmvballocator.EMVBallocator_memset(TVR,0,sizeof(TVR));
    dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_TVR,TVR,0,5);
	
	gEmvballocator.EMVBallocator_memset(TACDenial,0,sizeof(TACDenial));
    dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_TACDenial,TACDenial,0,5);
	gEmvballocator.EMVBallocator_memset(IACDenial,0,sizeof(IACDenial));
    IACDenialbExist = !(dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_IACDenial,IACDenial,0,5));
    
	
	
    if(IACDenialbExist == 0)
    {
    	for(i=0;i<5;i++)
		{
			if((TVR[i]&TACDenial[i])!=0)
			{
				return TAA_DENIAL;
			}
    	}
    }
	else
	{
		for(i=0;i<5;i++)
		{
			k=TVR[i];
			if((k&IACDenial[i])!=0) 
			{
				return TAA_DENIAL;
			}
			if((k&TACDenial[i])!=0) 
			{
				return TAA_DENIAL;
			}
		
		}
    
	}

    TermType = dllemvb_avl_gettagvalue((unsigned char *)TAG_TermType);
    //online only
    if(TermType == 0x11||TermType == 0x21||TermType == 0x14||
		TermType == 0x24||TermType == 0x34)
	{
		return TAA_ONLINE;
    }

    //not offline only
    if(TermType != 0x23&&TermType != 0x26&&TermType != 0x36&&
		TermType != 0x13&&TermType != 0x16){//Terminal has Online capability

        gEmvballocator.EMVBallocator_memset(TACOnline,0,sizeof(TACOnline));
	    dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_TACOnline,TACOnline,0,5);
		gEmvballocator.EMVBallocator_memset(IACOnline,0,sizeof(IACOnline));
	    IACOnlinebExist = !(dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_IACOnline,IACOnline,0,5));
	
		if(IACOnlinebExist==0)
		{
		    memcpy(TACOnlineOrValue, "\xff\xff\xff\xff\xfc", 5);

			for(i=0;i<5;i++)
			{
				if((TACOnline[i]|TACOnlineOrValue[i])&TVR[i])
				{
					return TAA_ONLINE;
				}
	    	}
			return TAA_OFFLINE;
		}
		else
		{
			for(i=0;i<5;i++){
				k=TVR[i];
				if((k & IACOnline[i])!=0) 
				{
					return TAA_ONLINE;
				}
				if((k & TACOnline[i])!=0) 
				{
					return TAA_ONLINE;
				}
			}
            
			return TAA_OFFLINE;
		}
		
	}
    
	gEmvballocator.EMVBallocator_memset(TACDefault,0,sizeof(TACDefault));
	dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_TACDefault,TACDefault,0,5);
	gEmvballocator.EMVBallocator_memset(IACDefault,0,sizeof(IACDefault));
	IACDefaultbExist = !(dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_IACDefault,IACDefault,0,5));
		
    if(IACDefaultbExist==0)
	{
        memcpy(TACOnlineOrValue, "\xff\xff\xff\xff\xfc", 5);
		for(i=0;i<5;i++)
		{
			if((TACDefault[i]|TACOnlineOrValue[i])&TVR[i])
			{
				return TAA_DENIAL;
			}
    	}
		return TAA_OFFLINE;
	}
	else
	{
		for(i=0;i<5;i++){
			k=TVR[i];
			if((k & IACDefault[i])!=0) return TAA_DENIAL;
			if((k & TACDefault[i])!=0) return TAA_DENIAL;
		}

		return TAA_OFFLINE;
	}
	
	
	
}



unsigned char paypassb_storerelayresistantdata(EMVBAppUnionStruct *tempApp_UnionStruct)
{
	
    unsigned char track2equ[30];
	unsigned short track2equlen;
	unsigned char asctrack2equ[80],PANlen = 0,discretionaryoffset,i;
	unsigned char capki;
	unsigned char DeviceRelayEntropy[4];
    unsigned int intDeviceRelayEntropy;
	EMVTAGCVLITEM *emvitem;
	
    if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_Track2Equ))
    {
		gEmvballocator.EMVBallocator_memset(track2equ,0,sizeof(track2equ));
		dllemvb_avl_gettagvalue_all((unsigned char *)TAG_Track2Equ,track2equ,&track2equlen);
		gEmvballocator.EMVBallocator_memset(asctrack2equ,0,sizeof(asctrack2equ));
	    EMVBcdToAsc(asctrack2equ,track2equ,track2equlen);
	    while(PANlen<(track2equlen<<1))
	    {
	        if(asctrack2equ[PANlen]>=0x30&&asctrack2equ[PANlen]<=0x39)
	        {
	    		PANlen++;
	        }
			else
			{
				break;
			}
			
	    }
		
		
		track2equlen = track2equlen<<1;
		if(track2equlen > 0)
		{
			if(asctrack2equ[track2equlen - 1] == 'F')
			{
				track2equlen -= 1;
			}
    	}
		
		discretionaryoffset = track2equlen;
		for(i = 0;i < track2equlen;i++)
		{
			
			if(asctrack2equ[i] == 'D')
			{
				discretionaryoffset = i+ 6;
				break;
			}
			
		}
		
		track2equlen = discretionaryoffset;
		//´óÐ´µÄA-F
	    if(PANlen <= 16)
	    {
	    	gEmvballocator.EMVBallocator_memset(&asctrack2equ[track2equlen],'0',13);
			track2equlen += 13;
	    }
		else
		{
			gEmvballocator.EMVBallocator_memset(&asctrack2equ[track2equlen],'0',10);
			track2equlen += 10;
		}
		
		

		
		
		//µÚÒ»¸ö×Ö½Ú  1
		if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_CAPKI))
		{
		    capki = dllemvb_avl_gettagvalue((unsigned char *)TAG_CAPKI);
			if(capki < 0x0A)
			{
				asctrack2equ[discretionaryoffset] = capki+0x30;
			}
			
		}
        discretionaryoffset++;

		
		//RRP counter   1
		asctrack2equ[discretionaryoffset] = dllemvb_avl_gettagvalue((unsigned char *)TAG_RRPCounter);
        if(asctrack2equ[discretionaryoffset]>0x09)
        {
        	asctrack2equ[discretionaryoffset] = 0x00;
        }
        asctrack2equ[discretionaryoffset] += 0x30;
		discretionaryoffset++;

		
		//Device Relay Resistance Entropy  5
		gEmvballocator.EMVBallocator_memset(DeviceRelayEntropy,0,sizeof(DeviceRelayEntropy));
		dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_DeviceRelayEntropy,DeviceRelayEntropy,0,4);
        intDeviceRelayEntropy = DeviceRelayEntropy[2];
		intDeviceRelayEntropy = (intDeviceRelayEntropy<<8) + DeviceRelayEntropy[3];

		sprintf((char *)&asctrack2equ[discretionaryoffset],"%05d",intDeviceRelayEntropy);
		discretionaryoffset += 5;
		
		
		//Application PAN  3
		emvitem = dllemvb_avl_gettagitempointer((unsigned char *)TAG_PAN);
		if(emvitem != NULL)
		{
			
			if(emvitem->len <=8)
			{
				intDeviceRelayEntropy = DeviceRelayEntropy[1];
				sprintf((char *)&asctrack2equ[discretionaryoffset],"%03d",intDeviceRelayEntropy);
				discretionaryoffset += 3;
			}
			
		}

		
        //Measured Relay Resistance Processint Time
        dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_MeasuredRelayProcessTime,DeviceRelayEntropy,0,2);
		intDeviceRelayEntropy = DeviceRelayEntropy[0];
		intDeviceRelayEntropy = (intDeviceRelayEntropy<<8) + DeviceRelayEntropy[1];
		intDeviceRelayEntropy = intDeviceRelayEntropy/10;
		if(intDeviceRelayEntropy>0x3e7)
		{
			intDeviceRelayEntropy = 0x3e7;
		}
		sprintf((char *)&asctrack2equ[track2equlen-3],"%03d",intDeviceRelayEntropy);
		

		if((track2equlen%2) != 0)
		{
			asctrack2equ[track2equlen++] = 'F';
		}
		
		
		EMVAscToBcd(track2equ,asctrack2equ,track2equlen);
        dllemvb_avl_createsettagvalue((unsigned char *)TAG_Track2Equ,track2equ,track2equlen>>1);



		
	}
	
	return EMV_OK;
	
}



//20140222
unsigned char Paypassb_GenerateRAC(EMVBAppUnionStruct *tempApp_UnionStruct,APDU_RESP *apdu_r,unsigned char type)
{
    unsigned char ret;
	unsigned char k,indexRet = 0;  //j,t,
	unsigned short index,indexTemp,lenTemp,orgindex;  //len,tmplen,,startpos
	//unsigned char Primitivetype = 0;
	unsigned char countpadding = 0;
	unsigned char bIntable;
	unsigned char GenerateACRetDataflag;
	unsigned char CryptInfo,reqCrpt;
	unsigned char CVMResult[3];//,TVR[5];
    EMVTAGCVLITEM *item;
	
    tempApp_UnionStruct->EMVTradeParam->GenerateACRetDataLen = 0;
	gEmvballocator.EMVBallocator_memset(tempApp_UnionStruct->EMVTradeParam->GenerateACRetData,0,255);
    
	
	// ÕâÀïÊÇ·ñÐèÒªÇå³ýtorn log
	if(!(apdu_r->SWA==0x90 && apdu_r->SWB==0x00))
	{
		return PAYPASS_SW1SW2ERR;
	}

	if(type == 0)
	{
		ret = tempApp_UnionStruct->deletetornlog();
	    if(ret != EMV_OK)
	    {
	    	return ret;
	    }

		ret = tempApp_UnionStruct->copytornrecorddata();
		if(ret != EMV_OK)
		{
			return ret;
		}

		//input pin,ÊÇ·ñÐèÒªÊäÈëpin½øÐÐÖØÐÂÅÐ¶Ï
        gEmvballocator.EMVBallocator_memset(CVMResult,0,sizeof(CVMResult));
		dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_CVMResult,CVMResult,0,3);
		if((CVMResult[0]&0x3F)==0x02 && CVMResult[2] == CVR_UNKNOWN)
		{
			tempApp_UnionStruct->EMVTradeParam->cvmonlinepinreq = 1;
		}
		else
		{
			tempApp_UnionStruct->EMVTradeParam->cvmonlinepinreq = 0;
            if((CVMResult[0]&0x3F)==0x1E && CVMResult[2] == CVR_UNKNOWN)
            {
            	tempApp_UnionStruct->EMVTradeParam->bPrintReceipt = 1;
            }
			else
			{
				tempApp_UnionStruct->EMVTradeParam->bPrintReceipt = 0;
			}
		}
	}
    
	#ifdef EMVB_DEBUG
    emvb_printf("\r\ndelete tag success\r\n");
	#endif
    
    index=0;
	if(apdu_r->DataOut[index]==0x80)//primitive data
	{
		index++;
        if(ParseExtLen(apdu_r->DataOut,&index,&lenTemp))
		{
			return ERR_EMV_IccDataFormat;
		}	

		
		#ifdef EMVB_DEBUG
        emvb_printf("\r\n80 len = %d %d %d\r\n",lenTemp,index,apdu_r->LenOut);
		#endif
		
		
		if((lenTemp+index) != apdu_r->LenOut)
		{
			return PAYPASS_ENDAPPLICATION;
		}
		
		
		if(lenTemp<11) return PAYPASS_ENDAPPLICATION;

		while(apdu_r->DataOut[index+countpadding] ==0)
		{
			countpadding++;
			if(countpadding >2)
				 return PAYPASS_ENDAPPLICATION;
		}
        
        if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_CryptInfo)||dllemvb_avl_checkiftagexist((unsigned char *)TAG_ATC)||
			dllemvb_avl_checkiftagexist((unsigned char *)TAG_AppCrypt))
        {
        	return ERR_EMV_IccDataFormat;
        }
		
		dllemvb_avl_set((unsigned char *)TAG_CryptInfo,apdu_r->DataOut[index]);
		index++;
        dllemvb_avl_createsettagvalue((unsigned char *)TAG_ATC,&apdu_r->DataOut[index],2);
		index += 2;
		dllemvb_avl_createsettagvalue((unsigned char *)TAG_AppCrypt,&apdu_r->DataOut[index],8);
		index += 8;
        
		if(apdu_r->LenOut>index){
			k=apdu_r->LenOut-index;
			if(k>32) return ERR_EMV_IccDataFormat;
			if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_IssuAppData))
			{
				return ERR_EMV_IccDataFormat;
			}
            
			dllemvb_avl_createsettagvalue((unsigned char *)TAG_IssuAppData,(unsigned char*)&apdu_r->DataOut[index],k);
			
		}
		
	}
	else if(apdu_r->DataOut[index]==0x77)//TLV coded data
	{
	    //Primitivetype = 1;
		index++;
		if(ParseExtLen(apdu_r->DataOut,&index,&lenTemp))
		{
		    #ifdef EMVB_DEBUG
            emvb_printf("\r\nerr120\r\n");
			#endif
			return ERR_EMV_IccDataFormat;
		}
		indexTemp=index;
		indexRet=0;
		while(index<indexTemp+lenTemp)
		{
			if(index>=apdu_r->LenOut)
			{
			    #ifdef EMVB_DEBUG
	            emvb_printf("\r\nerr121\r\n");
				#endif
				return PAYPASS_ENDAPPLICATION;
			}
			if(apdu_r->DataOut[index]==0xFF || apdu_r->DataOut[index]==0x00) 
			{ 
				index++; 
				continue;
			}

            orgindex = index;
            
			bIntable = 0;
			GenerateACRetDataflag = 1;
            
			if(!gEmvballocator.EMVBallocator_memcmp((unsigned char*)&apdu_r->DataOut[index],"\x9F\x4B",2))
			{
				GenerateACRetDataflag = 0;
			}
			ret = Paypassb_ParseAndStoreCardResponse(tempApp_UnionStruct,apdu_r->DataOut,&index,&bIntable,4);
			if(ret != EMV_OK)
			{
				return ret;
			}

			//20110406
			if(GenerateACRetDataflag&&(indexRet+index-orgindex <=255))
			{
				gEmvballocator.EMVBallocator_memcpy(tempApp_UnionStruct->EMVTradeParam->GenerateACRetData+indexRet,(unsigned char*)&apdu_r->DataOut[orgindex],index-orgindex);
				indexRet+=index-orgindex;
			}
            
		}	//endwhile
		if(index!=indexTemp+lenTemp)
		{
		    #ifdef EMVB_DEBUG
            emvb_printf("\r\nerr117\r\n");
			#endif
			return PAYPASS_ENDAPPLICATION;
		}
		
		if(index != apdu_r->LenOut)
		{
			return PAYPASS_ENDAPPLICATION;
		}

		//check if 9f27 len
		item = dllemvb_avl_gettagitempointer((unsigned char *)TAG_CryptInfo);
		if(item != NULL)
		{
			if(item->len == 0)
			{
				return PAYPASS_ENDAPPLICATION;
			}
		}
		
	}
	else
	{
		#ifdef EMVB_DEBUG
		emvb_printf("\r\nerr116\r\n");
		#endif
		
		return PAYPASS_ENDAPPLICATION;
		
	}

	tempApp_UnionStruct->EMVTradeParam->GenerateACRetDataLen = indexRet;

	
	
	if((dllemvb_avl_checkiftagexist((unsigned char *)TAG_CryptInfo)==0)||
			(dllemvb_avl_checkiftagexist((unsigned char *)TAG_ATC)==0))
	{
        #ifdef EMVB_DEBUG
        emvb_printf("\r\nerr111\r\n");
		#endif
		
		return PAYPASS_CARDDATAMISSING;
		
	}
    
	
    CryptInfo = dllemvb_avl_gettagvalue((unsigned char *)TAG_CryptInfo);
	reqCrpt = dllemvb_avl_gettagvalue((unsigned char *)TAG_ReferenceControlParameter);
	
    if((CryptInfo&0xc0) == 0x40&&(reqCrpt&TAA_OFFLINE))
    {
    	
    }
	else if((CryptInfo&0xc0) == 0x80&&((reqCrpt&TAA_OFFLINE) || (reqCrpt&TAA_ONLINE)))
    {
    	
    }
	else if((CryptInfo&0xc0) == 0x00)
    {
    	
    }
	else
	{
		return PAYPASS_CARDDATAERR;
	}

	
	
    
	
    
	
	return EMV_OK;
    
	
}

/*******************************************************************
×÷    Õß:
º¯ÊýÃû³Æ: unsigned char Paypass_CommandGAC1(AppUnionStruct *tempApp_UnionStruct,unsigned char TermAnaResult,APDU_SEND *apdu_s)
º¯Êý¹¦ÄÜ: PAYPASS GAC1
Èë¿Ú²ÎÊý:
·µ »Ø Öµ:
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:     20140222
********************************************************************/
unsigned char Paypassb_CommandGAC1(EMVBAppUnionStruct *tempApp_UnionStruct,unsigned char TermAnaResult,APDU_SEND *apdu_s)
{
	unsigned char retCode = EMV_OK;//TermAnaResult,CardAnaResult;//0-Denial,1-Online,2-Offline
	unsigned short len,dsdollen;
    //unsigned char SubAmount[6];
	unsigned char TVR[5],AIP[2],KernelConfig;
	unsigned char *CDOL1;   //[255]
	unsigned short CDOL1Len;
    unsigned char CDAflag = 0;
	unsigned char AppCapabilitiesInfor[3];
    unsigned char entrytype = 1;
	unsigned char dsactype,actype,dsodsinfoforreader;
	EMVTAGCVLITEM *item;
	unsigned char dsinputterm[8];
	

	gEmvballocator.EMVBallocator_memset(TVR,0,sizeof(TVR));
	dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_TVR,TVR,0,5);

    gEmvballocator.EMVBallocator_memset(AIP,0,sizeof(AIP));
	dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AIP,AIP,0,2);

	KernelConfig = dllemvb_avl_gettagvalue((unsigned char *)TAG_KernelConfiguration);
	
	if(TermAnaResult == TAA_ONLINE)
	{
		actype = DS_ACTYPE_ARQC;
	}
	else if(TermAnaResult == TAA_OFFLINE)
	{
		actype = DS_ACTYPE_TC;
	}
	else
	{
		actype = DS_ACTYPE_AAC;
	}
	
	// GAC.1
	if(dllemvb_avl_gettagvalue((unsigned char *)TAG_IDSStatus)&0x80)
	{
	    //GAC.2
		if(TVR[0]&0x04) // CDA fail
		{
			//GAC.D

			entrytype = 4;
			
		}
		else
		{
			 //GAC.3
			 if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_DSODSInfo))
			 {
			 	
			 	 //GAC.4
				 if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_DSDOL))
				 {
				 	if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_DSACType)&&dllemvb_avl_checkiftagexist((unsigned char *)TAG_DSODSInfoReader))
				 	{
				 		//GAC.7
				 		dsactype = dllemvb_avl_gettagvalue((unsigned char *)TAG_DSACType);
						dsactype = dsactype>>6;
						dsodsinfoforreader = dllemvb_avl_gettagvalue((unsigned char *)TAG_DSODSInfoReader);
						if((dsactype==DS_ACTYPE_AAC)||(actype == dsactype)||((dsactype==DS_ACTYPE_ARQC)&&(actype == DS_ACTYPE_TC)))
						{
							 //GAC.8
							 if(dsactype == DS_ACTYPE_TC)
							 {
							 	TermAnaResult = TAA_OFFLINE;
							 }
							 else if(dsactype == DS_ACTYPE_ARQC)
							 {
							 	TermAnaResult = TAA_ONLINE;
							 }
							 else
							 {
							 	TermAnaResult = TAA_DENIAL;
							 }
						}
						else
						{
							//GAC.9
							if((actype == DS_ACTYPE_AAC&&(dsodsinfoforreader&0x20))||(actype == DS_ACTYPE_ARQC&&(dsodsinfoforreader&0x40)))
							{
								//GAC.40
								//AÈë¿Ú
								
							}
							else
							{
								// GAC.10
								if(dsodsinfoforreader&0x04)
								{
									// GAC.11
									Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_GAC_11);
									retCode = ERR_EMV_IccDataFormat;
								}
								else
								{
									//GAC.27
									entrytype = 3;
								}
								
							}
							 
						}
						
				 	}
					else
					{
						//GAC.6
						Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_GAC_6);
						retCode = ERR_EMV_IccDataFormat;
					}
				 }
				 else
				 {
				 	//GAC.27
					entrytype = 3;
				 }
				
			 }
			 else
			 {
			 	//GAC.27
				entrytype = 3;
				
			 }
		}
	}
    else
    {
		//// GAC.B.20
		entrytype = 2;
	}

	 //GAC.12
    if(retCode != EMV_OK)
    {
    	
    	Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_GAC_12);
		Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_GAC_13);
		return PAYPASS_ENDAPPLICATION;
		
    }
	

	
	if(entrytype == 1)  //GAC A  IDS Write
	{
		if(Paypassb_CheckTagInDOL((unsigned char *)TAG_DSDOL,(unsigned char *)TAG_DSDigestH) >=0)
		{
		     //GAC.41
			item = dllemvb_avl_gettagitempointer((unsigned char *)TAG_DSInputTerm);
			if(item != NULL)
			{
				//GAC.42
				gEmvballocator.EMVBallocator_memset(AppCapabilitiesInfor,0,sizeof(AppCapabilitiesInfor));
				dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AppCapabilitiesInfor,AppCapabilitiesInfor,0,3);
                gEmvballocator.EMVBallocator_memset(dsinputterm,0,sizeof(dsinputterm));
				gEmvballocator.EMVBallocator_memcpy(dsinputterm,item->data,item->len);
				if((AppCapabilitiesInfor[0]&0x0F) == 0x01)
				{
					//GAC.43
					paypassb_OWHF2(tempApp_UnionStruct,dsinputterm,dsinputterm);
					
				}
				else
				{
					//GAC.44
					paypassb_OWHF2AES(tempApp_UnionStruct,dsinputterm,dsinputterm);
					
				}
				dllemvb_avl_createsettagvalue((unsigned char *)TAG_DSDigestH,dsinputterm,8);
				
				
			}
			
		}
		
		//GAC.45
		CDAflag = 1;
		//GAC.47
		dllemvb_avl_setvalue_or((unsigned char *)TAG_IDSStatus,0,0x40);
		
		
	}
	else if(entrytype == 2) // GAC B NO IDS
	{
		if(tempApp_UnionStruct->EMVTradeParam->ODAstaus)
		{
			
	        if(TVR[0]&0x04) // CDA fail GAC.21
	        {
	        	if((AIP[0]&0x02)&&(KernelConfig&0x20)) //GAC.22
	        	{
	        		TermAnaResult = TAA_DENIAL;
	        	}
	        }
			else
			{
				if(TermAnaResult == TAA_DENIAL) //GAC.24
				{
					gEmvballocator.EMVBallocator_memset(AppCapabilitiesInfor,0,sizeof(AppCapabilitiesInfor));
					dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AppCapabilitiesInfor,AppCapabilitiesInfor,0,3);
                    //GAC.25
					if(AppCapabilitiesInfor[1]&0x01)
					{
						CDAflag = 1;
					}
				}
				else
				{
					CDAflag = 1;
				}
			}
		}
#if 0   //GAC.26
		else
		{
			if((AIP[0]&0x02)&&(KernelConfig&0x20))
	    	{
	    		TermAnaResult = TAA_DENIAL;
	    	}
		}
#endif
	}
	else if(entrytype == 3)
	{
		CDAflag = 1;
	}
	else if(entrytype == 4)
	{
		if((AIP[0]&0x02)&&(KernelConfig&0x20)) //GAC.22
    	{
    		TermAnaResult = TAA_DENIAL;
    	}
	}
	
   


	
    
    gEmvballocator.EMVBallocator_memcpy(apdu_s->Command,"\x80\xAE\x00\x00",4);
	apdu_s->Command[2] = TermAnaResult;
    if(CDAflag)
    {
    	apdu_s->Command[2] |= 0x10;
    }

	dllemvb_avl_set((unsigned char *)TAG_ReferenceControlParameter,apdu_s->Command[2]);

	CDOL1 = (unsigned char *)emvblib_malloc(255);
    dllemvb_avl_gettagvalue_all((unsigned char *)TAG_CDOL1,CDOL1,&CDOL1Len);
	len = 0;
	
	
	retCode = Paypassb_DOLProcess(typeCDOL1,CDOL1,CDOL1Len,apdu_s->DataIn,&len,tempApp_UnionStruct);
    if(retCode == EMV_OK)
    {
    	dllemvb_avl_createsettagvalue((unsigned char *)TAG_CDOL1RelatedData,apdu_s->DataIn,len);
        if(dllemvb_avl_gettagvalue((unsigned char *)TAG_IDSStatus)&0x40)
        {
	    	dllemvb_avl_gettagvalue_all((unsigned char *)TAG_DSDOL,CDOL1,&CDOL1Len);
			dsdollen = 0;
	    	retCode = Paypassb_DOLProcess(typeDSDOL,CDOL1,CDOL1Len,&apdu_s->DataIn[len],&dsdollen,tempApp_UnionStruct);
            len += dsdollen;
		}
		
    }
    emvblib_free(CDOL1);
	#ifdef EMVB_DEBUG
    emvb_printf("\r\n Emv_CommandGAC12\r\n");
	#endif
	
	//if(retCode == EMV_OK)
	//{
	//    dllemvb_avl_createsettagvalue((unsigned char *)TAG_CDOL1RelatedData,apdu_s->DataIn,len);
	//}
	apdu_s->Lc=len;
	apdu_s->Le=256;
	apdu_s->EnableCancel = 0;
	
	return retCode;
	
}


void Paypassb_Invalidresponse(EMVBAppUnionStruct *tempApp_UnionStruct)
{
	Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S10_E50_0);

	//S11.90
    if(tempApp_UnionStruct->EMVTradeParam->paypassgacresponsetype)
    {
        //S11.91
    	if(tempApp_UnionStruct->EMVTradeParam->IDSStatusInTorn&0x40)
    	{
    		tempApp_UnionStruct->retrivesavedtornrecord();
    	}
    }
	
	//Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S10_E53_0);
	if(dllemvb_avl_gettagvalue((unsigned char *)TAG_IDSStatus)&0x40)
	{
		Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S10_E52_0);
	}
	else
	{
		Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S10_E53_0);
	}
}

/*******************************************************************
×÷    Õß:
º¯ÊýÃû³Æ: unsigned char Paypass_TermiAnalys(AppUnionStruct *tempApp_UnionStruct)
º¯Êý¹¦ÄÜ: PaypassÖÕ¶ËÐÐÎª·ÖÎö
Èë¿Ú²ÎÊý:
·µ »Ø Öµ:
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:   20140222
********************************************************************/
unsigned char Paypassb_TermiAnalys(EMVBAppUnionStruct *tempApp_UnionStruct,unsigned char TermAnaResult)
{
	
	unsigned char retCode;
	//unsigned char TermAnaResult;
    APDU_SEND apdu_s;
	APDU_RESP apdu_r;
	//unsigned char temptransTypeValue;
	
	#if 0
    TermAnaResult = Paypassb_TermActAnaly(tempApp_UnionStruct);

	temptransTypeValue = dllemvb_avl_gettagvalue((unsigned char *)TAG_TransTypeValue);
	if(temptransTypeValue == 0x09)
	{
	    if(TermAnaResult = TAA_OFFLINE)
	    {
			TermAnaResult = TAA_ONLINE;
	    }
	}
	#endif
    tempApp_UnionStruct->EMVTradeParam->paypassgacresponsetype = 0;
	if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_DRDOL)&&dllemvb_avl_gettagvalue((unsigned char *)TAG_MaxNumTornLog))
	{
		retCode = tempApp_UnionStruct->checkifcardintornlog();
		if(retCode)
		{
		    retCode = tempApp_UnionStruct->RECOVERAC(&apdu_s);
			apdu_s.EnableCancel = 0;
			if(retCode != EMV_OK)
			{
				return PAYPASS_ENDAPPLICATION;
			}
            
            tempApp_UnionStruct->EMVB_qPBOCIccIsoCommand(&apdu_s,&apdu_r);
    		if(apdu_r.ReadCardDataOk != EMV_OK)
    		{
    		    
    			tempApp_UnionStruct->freetornlogtempdata(ERR_APP_TIMEOUT);
				Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S10_E5_0);
				Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S10_E6_0);
			    return ERR_APP_TIMEOUT;
    		}

			retCode = Paypassb_GenerateRAC(tempApp_UnionStruct,&apdu_r,0);
			tempApp_UnionStruct->freetornlogtempdata(retCode);
            if(retCode != PAYPASS_SW1SW2ERR)
            {
                
            	if(retCode != EMV_OK)
				{
					
					if(retCode == PAYPASS_CARDDATAERR)
					{
						Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S10_E18_0);
					}
					else if(retCode == PAYPASS_CARDDATAMISSING)
					{
						Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S10_E16_0);
					}
                    else
                    {
						Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S10_E14_0);
                    }
					Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S10_E50_0);
					if(dllemvb_avl_gettagvalue((unsigned char *)TAG_IDSStatus)&0x40)
					{
						Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S10_E52_0);
					}
					else
					{
						Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S10_E53_0);
					}
				    return PAYPASS_ENDAPPLICATION;
					
				}
				
				return EMV_OK;
				
            }
            else
            {
                //copy old data
                
            	tempApp_UnionStruct->EMVTradeParam->paypassgacresponsetype = 1;
            }
			
		}
	}

    
	
	
    retCode = Paypassb_CommandGAC1(tempApp_UnionStruct,TermAnaResult,&apdu_s);
	if(retCode != EMV_OK)
	{
		return PAYPASS_ENDAPPLICATION;
	}

	tempApp_UnionStruct->EMVB_qPBOCIccIsoCommand(&apdu_s,&apdu_r);
    if(apdu_r.ReadCardDataOk != EMV_OK)
    {
        if(tempApp_UnionStruct->EMVTradeParam->paypassgacresponsetype)
        {
        	//S11.11
        	if((tempApp_UnionStruct->EMVTradeParam->IDSStatusInTorn&0x40)== 0)
        	{
        		//S11.12
				tempApp_UnionStruct->deletetornlog();
        	}
        }
		
    	if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_DRDOL)&&dllemvb_avl_gettagvalue((unsigned char *)TAG_MaxNumTornLog))
    	{
    		tempApp_UnionStruct->addtornlog((uintptr_t)tempApp_UnionStruct);    //sxl?202264位机指针
			Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S9_E14_0);
			Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S9_E15_0);
            return PAYPASS_ENDAPPLICATION;
    	}
		else
		{
		    //S9.6 
		    if((dllemvb_avl_gettagvalue((unsigned char *)TAG_IDSStatus)&0x40)&&(tempApp_UnionStruct->EMVTradeParam->paypassgacresponsetype == 0)) //IDS Write Flag set
		    {
		    	Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S9_7);
				Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S9_8);
				return ERR_APP_TIMEOUT;
		    }
			else
			{
				
				Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S9_E9_0);
				Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S9_E10_0);
	            return ERR_APP_TIMEOUT;
				
			}
		}
    }

	if(tempApp_UnionStruct->EMVTradeParam->paypassgacresponsetype)
	{
		tempApp_UnionStruct->deletetornlog();
	}

    retCode = Paypassb_GenerateRAC(tempApp_UnionStruct,&apdu_r,1);
                
	#ifdef EMVB_DEBUG
    emvb_printf("\r\nEmv_TermiAnalys22\r\n");
	#endif
	
	if(retCode != EMV_OK)
	{
		if(retCode == PAYPASS_SW1SW2ERR)
		{
            Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S9_E17_0);
		}
		else if(retCode == PAYPASS_CARDDATAMISSING)
		{
			Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S10_E22_0);
		}
		else if(retCode == PAYPASS_CARDDATAERR)
		{
			Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S10_E24_0);
		}
        else
        {
			Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S10_E20_0);
        }
		 //S910 Invalid response - 1
		Paypassb_Invalidresponse(tempApp_UnionStruct);
	    return PAYPASS_ENDAPPLICATION;
		
	}
	
	return EMV_OK;
    
}


//20140222
unsigned char Paypassb_GenACBalanceRead(EMVBAppUnionStruct *tempApp_UnionStruct)
{
	//unsigned char retCode = EMV_OK;
    APDU_SEND apdu_s;
	APDU_RESP apdu_r;
	unsigned char AppCapabilitiesInfor[3];
	EMVTAGCVLITEM *item;

	gEmvballocator.EMVBallocator_memset(AppCapabilitiesInfor,0,sizeof(AppCapabilitiesInfor));
	dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AppCapabilitiesInfor,AppCapabilitiesInfor,0,3);
    if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_BalanceAfterGAC))
	{
		dllemvb_avl_createsettagvalue((unsigned char *)TAG_BalanceAfterGAC,NULL,0);
	}
	item = dllemvb_avl_gettagitempointer((unsigned char *)TAG_BalanceAfterGAC);
	
	if((AppCapabilitiesInfor[1]&0x02)&&(item!= NULL))
	{
		gEmvballocator.EMVBallocator_memset(&apdu_s,0,sizeof(APDU_SEND));
		gEmvballocator.EMVBallocator_memcpy(apdu_s.Command,"\x80\xCA\x9F\x50",4);
		apdu_s.Le = 0;
		apdu_s.EnableCancel = 0;
        
        tempApp_UnionStruct->EMVB_qPBOCIccIsoCommand(&apdu_s,&apdu_r);
    	if(apdu_r.ReadCardDataOk == EMV_OK)
		{
			Paypassb_ReadBalanceRetData(&apdu_r,1);
		}
	}
    
    //tempApp_UnionStruct->promptremovecardsoundled();  //?2017	
	return EMV_OK;
	
}



/*******************************************************************
×÷    Õß:
º¯ÊýÃû³Æ: unsigned char Paypassb_CombineDDA_FirstHalf(Msg *msg)
º¯Êý¹¦ÄÜ: ÍÑ»úÊý¾ÝÈÏÖ¤
Èë¿Ú²ÎÊý:
·µ »Ø Öµ:
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:   20140222
********************************************************************/
unsigned char Paypassb_CombineDDA_FirstHalf(EMVBAppUnionStruct *tempApp_UnionStruct)
{
	
	if(tempApp_UnionStruct->IPKModulLen==0)
	{
		if(Emvb_GetIPK(tempApp_UnionStruct)!=EMV_OK)		//retrieval of the issuer public key modulus
		{
			#ifdef EMVB_DEBUG
			emvb_printf("\nGet IPK fail");
			#endif
			return EMV_ERR;
		}
	}
	
    
    
	if(tempApp_UnionStruct->ICCPKModulLen==0)
	{
		if(Emvb_GetICCPK(tempApp_UnionStruct)!=EMV_OK)			//retrieval of the ICC public key
		{
			#ifdef EMVB_DEBUG
			emvb_printf("\nGet ICCPK fail");
			emvb_printf("ICCPK run2");
			#endif
			return EMV_ERR;
		}
	}
	

	return EMV_OK;
}


/*******************************************************************
��    ��:
��������: unsigned char Paypassb_FillSDA(AppUnionStruct *tempApp_UnionStruct)
��������: �ȶԶ�̬ǩ������
��ڲ���:
�� �� ֵ:
��ص���:
��    ע:
�޸���Ϣ:  20131023
********************************************************************/
unsigned char Paypassb_FillSDA(unsigned char* SDAData,SIGN_DYN_APPDATA_RECOVER* recovSDA,unsigned char tempICCPKModulLen)
{
    unsigned char LDD,i;
    recovSDA->DataHead=SDAData[0];
    recovSDA->DataFormat=SDAData[1];
    recovSDA->HashInd=SDAData[2];
    recovSDA->ICCDynDataLen=SDAData[3];
    LDD=SDAData[3];
    if(tempICCPKModulLen < 25)
    {
        return EMV_ERR;
    }
    if(LDD>tempICCPKModulLen-25)
        return EMV_ERR;
    memcpy(recovSDA->ICCDynData,(unsigned char*)&SDAData[4],LDD);
    memcpy(recovSDA->PadPattern,(unsigned char*)&SDAData[LDD+4],tempICCPKModulLen-LDD-25);
    for(i=0;i<20;i++)
        recovSDA->HashResult[i]=SDAData[tempICCPKModulLen-21+i];
    recovSDA->DataTrail=SDAData[tempICCPKModulLen-1];
    return EMV_OK;
}

/*******************************************************************
��    ��:
��������: void Paypassb_FillICCDynData(unsigned char* DynData,ICC_DYN_DATA* ICCDynData)
��������: ��䶯̬ǩ��
��ڲ���: ��
�� �� ֵ: ��
��ص���:
��    ע:
�޸���Ϣ:  20131023
********************************************************************/
void Paypassb_FillICCDynData(unsigned char ICCDynDataLen,unsigned char* DynData,ICC_DYN_DATA* ICCDynData,unsigned char cdatype,unsigned char aciversion)
{
    unsigned char Ldn;
    Ldn=DynData[0];
    ICCDynData->ICCDynNumLen=Ldn;
    memcpy(ICCDynData->ICCDynNum,DynData+1,Ldn);
    ICCDynData->CryptInfo=DynData[Ldn+1];
    memcpy(ICCDynData->AppCrypt,DynData+Ldn+2,8);
    memcpy(ICCDynData->HashResult,DynData+Ldn+10,20);

    if(cdatype == 1)
    {
        if(aciversion == 0x02)
        {
            ICCDynData->DSSummary2len = 16;
            ICCDynData->DSSummary3len = 16;
        }
        else
        {
            ICCDynData->DSSummary2len = 8;
            ICCDynData->DSSummary3len = 8;
        }
        memcpy(ICCDynData->DSSummary2,DynData+Ldn+30,ICCDynData->DSSummary2len);
        memcpy(ICCDynData->DSSummary3,DynData+Ldn+30+ICCDynData->DSSummary2len,ICCDynData->DSSummary3len);
        memcpy(ICCDynData->TerminalRelayEntropyCDA,DynData+Ldn+30+(ICCDynData->DSSummary2len+ICCDynData->DSSummary3len),4);
        memcpy(ICCDynData->DeviceRelayEntropyCDA,DynData+Ldn+34+(ICCDynData->DSSummary2len+ICCDynData->DSSummary3len),4);
        memcpy(ICCDynData->MintimeforRelayAPDUCDA,DynData+Ldn+38+(ICCDynData->DSSummary2len+ICCDynData->DSSummary3len),2);
        memcpy(ICCDynData->MaxtimeforRelayAPDUCDA,DynData+Ldn+40+(ICCDynData->DSSummary2len+ICCDynData->DSSummary3len),2);
        memcpy(ICCDynData->DevEstTransTimeForRelayCDA,DynData+Ldn+42+(ICCDynData->DSSummary2len+ICCDynData->DSSummary3len),2);

    }
    else if(cdatype == 2)
    {
        if(aciversion == 0x02)
        {
            if(ICCDynDataLen >=(30+16+Ldn))
            {
                ICCDynData->DSSummary2len = 16;
                 memcpy(ICCDynData->DSSummary2,DynData+Ldn+30,ICCDynData->DSSummary2len);
            }

            if(ICCDynDataLen >=(30+32+Ldn))
            {
                ICCDynData->DSSummary3len = 16;
                 memcpy(ICCDynData->DSSummary3,DynData+Ldn+30+ICCDynData->DSSummary2len,ICCDynData->DSSummary3len);
            }

        }
        else
        {
            if(ICCDynDataLen >=(30+8+Ldn))
            {
                ICCDynData->DSSummary2len = 8;
                 memcpy(ICCDynData->DSSummary2,DynData+Ldn+30,ICCDynData->DSSummary2len);
            }

            if(ICCDynDataLen >=(30+16+Ldn))
            {
                ICCDynData->DSSummary3len = 8;
                 memcpy(ICCDynData->DSSummary3,DynData+Ldn+30+ICCDynData->DSSummary2len,ICCDynData->DSSummary3len);
            }
        }
    }
    else if(cdatype == 3)
    {
        memcpy(ICCDynData->TerminalRelayEntropyCDA,DynData+Ldn+30,4);
        memcpy(ICCDynData->DeviceRelayEntropyCDA,DynData+Ldn+34,4);
        memcpy(ICCDynData->MintimeforRelayAPDUCDA,DynData+Ldn+38,2);
        memcpy(ICCDynData->MaxtimeforRelayAPDUCDA,DynData+Ldn+40,2);
        memcpy(ICCDynData->DevEstTransTimeForRelayCDA,DynData+Ldn+42,2);
    }

}

/*******************************************************************
��    ��:
��������: unsigned char Paypassb_CombineDDASignVerify(unsigned char type,AppUnionStruct *tempApp_UnionStruct)
��������: ����������֤
��ڲ���: ��
�� �� ֵ: ��
��ص���:
��    ע:
�޸���Ϣ:    20140222
********************************************************************/
unsigned char Paypassb_CombineDDASignVerify(unsigned char type,EMVBAppUnionStruct *tempApp_UnionStruct)
{
    unsigned char *SDAToSign,SDAHash[20],*SDAData,i=0;  //[512]    [248]
    unsigned int index;
    SIGN_DYN_APPDATA_RECOVER *recovSDA;
    ICC_DYN_DATA ICCDynDataSign;
    EMVTAGCVLITEM *SignDynAppDataitem,*ICCPKExpitem,*DOLDataitem;
    unsigned char CryptInfo;
    unsigned char UnpredictNum[4];
    unsigned char cdatype = 0,rrpperformed,aciversion;
    unsigned char tempbuf[4];


    #ifdef EMVB_DEBUG
    int k;
    #endif


    if((dllemvb_avl_checkiftagexist((unsigned char *)TAG_CryptInfo)== 0)||(dllemvb_avl_checkiftagexist((unsigned char *)TAG_SignDynAppData)==0)
        ||(dllemvb_avl_checkiftagexist((unsigned char *)TAG_ATC)==0))
    {
        #ifdef EMVB_DEBUG
        emvb_printf("\r\n Paypassb_CombineDDASignVerify111");
        #endif
        return ERR_EMV_CDAFORMAT;
    }


    memset((unsigned char*)&ICCDynDataSign,0,sizeof(ICC_DYN_DATA));




    memset(SDAHash,0,20);

    SignDynAppDataitem = dllemvb_avl_gettagitempointer((unsigned char *)TAG_SignDynAppData);

    if(SignDynAppDataitem->len!=tempApp_UnionStruct->ICCPKModulLen)
    {
        return EMV_ERR;
    }

    ICCPKExpitem = dllemvb_avl_gettagitempointer((unsigned char *)TAG_ICCPKExp);

    #ifdef EMVB_DEBUG
    emvb_printf("\nPaypassb SignDynAppData: ");
    for(i=0;i<SignDynAppDataitem->len;i++)
        emvb_printf("%02X",SignDynAppDataitem->data[i]);
    emvb_printf("\nICCPKModul");
    for(i=0;i<tempApp_UnionStruct->ICCPKModulLen;i++)
        emvb_printf("%02X",tempApp_UnionStruct->ICCPKModul[i]);
    emvb_printf("\nCardInfo.ICCPKExp");
    for(i=0;i<ICCPKExpitem->len;i++)
        emvb_printf("%02X",ICCPKExpitem->data[i]);
    #endif

    SDAData = (unsigned char *)emvblib_malloc(248);
    tempApp_UnionStruct->emv_arith_rsarecover(tempApp_UnionStruct->ICCPKModul,tempApp_UnionStruct->ICCPKModulLen,ICCPKExpitem->data,ICCPKExpitem->len,SignDynAppDataitem->data,SDAData);

    #ifdef EMVB_DEBUG
    emvb_printf("\nRecovered SDAD: ");
    for(i=0;i<tempApp_UnionStruct->ICCPKModulLen;i++)
        emvb_printf("%02X",SDAData[i]);
    #endif

    recovSDA = (SIGN_DYN_APPDATA_RECOVER *)emvblib_malloc(sizeof(SIGN_DYN_APPDATA_RECOVER));


    if(Paypassb_FillSDA(SDAData,recovSDA,tempApp_UnionStruct->ICCPKModulLen)!=EMV_OK)
    {
        #ifdef EMVB_DEBUG
        emvb_printf("\r\n Paypassb_CombineDDASignVerify115");
        #endif
        emvblib_free(recovSDA);
        emvblib_free(SDAData);
        return EMV_ERR;
    }

    #ifdef EMVB_DEBUG
    emvb_printf("\r\n Paypassb_CombineDDASignVerify111 %02x %02x %02x",recovSDA->DataTrail,recovSDA->DataHead,recovSDA->DataFormat);
    #endif

    if(recovSDA->DataTrail!=0xBC)       //If it is not ??BC??, dynamic data authentication has failed.
    {
        emvblib_free(recovSDA);
        emvblib_free(SDAData);
        return EMV_ERR;
    }
    if(recovSDA->DataHead!=0x6A)        //If it is not ??6A??, dynamic data authentication has failed.
    {
        emvblib_free(recovSDA);
        emvblib_free(SDAData);
        return EMV_ERR;
    }
    if(recovSDA->DataFormat!=0x05)  //If it is not ??05??, dynamic data authentication has failed.
    {
        emvblib_free(recovSDA);
        emvblib_free(SDAData);
        return EMV_ERR;
    }

    dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_TVR,&rrpperformed,4,1);
    rrpperformed &= 0x03;
    //IDS read flag set //S910.2
    if(dllemvb_avl_gettagvalue((unsigned char *)TAG_IDSStatus)&0x80)
    {
        //S910.2.2
        if(rrpperformed==0x02)
        {
            //S910.3.1
            cdatype = 1;
        }
        else
        {
            cdatype = 2;
        }
    }
    else
    {

        if(rrpperformed==0x02)
        {
            cdatype = 3;
        }

    }

    aciversion = 0;
    dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AppCapabilitiesInfor,&aciversion,0,1);
    aciversion &= 0x0F;


    Paypassb_FillICCDynData(recovSDA->ICCDynDataLen,recovSDA->ICCDynData,&ICCDynDataSign,cdatype,aciversion);


    if((cdatype == 1&&aciversion== 1&&(60+ICCDynDataSign.ICCDynNumLen)>recovSDA->ICCDynDataLen)
        ||(cdatype == 1&&aciversion== 2&&(76+ICCDynDataSign.ICCDynNumLen)>recovSDA->ICCDynDataLen)
        ||(cdatype == 2&&(30+ICCDynDataSign.ICCDynNumLen)>recovSDA->ICCDynDataLen)
        ||(cdatype == 3&&(44+ICCDynDataSign.ICCDynNumLen)>recovSDA->ICCDynDataLen)
        ||(cdatype == 0&&(30+ICCDynDataSign.ICCDynNumLen)>recovSDA->ICCDynDataLen))
    {
        emvblib_free(recovSDA);
        emvblib_free(SDAData);
        return EMV_ERR;
    }

    CryptInfo = dllemvb_avl_gettagvalue((unsigned char *)TAG_CryptInfo);
    if(ICCDynDataSign.CryptInfo!= CryptInfo)   // v2cc127000 ������Ҫ�����µ��ĵ�
    {
        if((ICCDynDataSign.CryptInfo&0xC0)==0x80)
        {
            #ifdef EMVB_DEBUG
            emvb_printf("\r\n Emv_CombineDDASignVerify116");
            #endif
            emvblib_free(recovSDA);
            emvblib_free(SDAData);
            return ERR_EMV_CDADifferCID;
        }
        else if((ICCDynDataSign.CryptInfo&0xC0)==0x40)
        {
            #ifdef EMVB_DEBUG
            emvb_printf("\r\n Emv_CombineDDASignVerify117");
            #endif
            emvblib_free(recovSDA);
            emvblib_free(SDAData);
            return ERR_EMV_CDADifferCIDTC;
        }
        else
        {
            emvblib_free(recovSDA);
            emvblib_free(SDAData);
            return  EMV_ERR;
        }
    }

    SDAToSign = (unsigned char *)emvblib_malloc(512+64);
    index=0;
    memset(SDAToSign,0,512+64);
    memcpy(SDAToSign,(unsigned char*)&SDAData[1],tempApp_UnionStruct->ICCPKModulLen-22);
    index+=tempApp_UnionStruct->ICCPKModulLen-22;


    emvblib_free(SDAData);


    if(GenerateAC2 == type)
    {
        i = tempApp_UnionStruct->EMVTradeParam->bCDOL2HasNoUnpredictNum;
    }
    if(GenerateAC1 == type)
    {
        i = tempApp_UnionStruct->EMVTradeParam->bCDOL1HasNoUnpredictNum;
    }
    #ifdef EMVB_DEBUG
    emvb_printf("i=%02x",i);
    #endif
    if(i == 0)
    {
        dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_UnpredictNum,UnpredictNum,0,4);
        memcpy((unsigned char*)&SDAToSign[index],UnpredictNum,4);
        index+=4;
    }
    else    // v2cc13301 �����Ƿ�Ҫ�޸�
    {

    }


    if(recovSDA->HashInd!=0x01)//SHA-1 algorithm
    {
        #ifdef EMVB_DEBUG
        emvb_printf("\r\n Paypassb_CombineDDASignVerify118");
        #endif
        emvblib_free(recovSDA);
        emvblib_free(SDAToSign);
        return EMV_ERR;
    }

    //Hash(SDAToSign,index,SDAHash);
    tempApp_UnionStruct->emv_arith_hash(SDAToSign, index, SDAHash, 0);


    if(memcmp(recovSDA->HashResult,SDAHash,20))
    {
        #ifdef EMVB_DEBUG
        emvb_printf("\r\n Paypassb_CombineDDASignVerify119");
        #endif
        emvblib_free(recovSDA);
        emvblib_free(SDAToSign);
        return EMV_ERR;
    }

    emvblib_free(recovSDA);

    memset(SDAToSign,0,512+64);
    memset(SDAHash,0,20);
    index=0;

    DOLDataitem = dllemvb_avl_gettagitempointer((unsigned char *)TAG_PDOLData);

    if(DOLDataitem != NULL)
    {
        if(DOLDataitem->len)
        {
            memcpy(SDAToSign,DOLDataitem->data,DOLDataitem->len);
            index+=DOLDataitem->len;
        }
    }

    DOLDataitem = dllemvb_avl_gettagitempointer((unsigned char *)TAG_CDOL1RelatedData);
    if(DOLDataitem != NULL)
    {
        if(DOLDataitem->len)
        {
            memcpy(SDAToSign+index,DOLDataitem->data,DOLDataitem->len);
            index+=DOLDataitem->len;
        }
    }


    if(type==GenerateAC2)
    {
        DOLDataitem = dllemvb_avl_gettagitempointer((unsigned char *)TAG_CDOL2RelatedData);
        if(DOLDataitem != NULL)
        {
            if(DOLDataitem->len)
            {
                memcpy(SDAToSign+index,DOLDataitem->data,DOLDataitem->len);
                index+=DOLDataitem->len;
            }
        }
    }

    memcpy(SDAToSign+index,tempApp_UnionStruct->EMVTradeParam->GenerateACRetData,tempApp_UnionStruct->EMVTradeParam->GenerateACRetDataLen);
    index+=tempApp_UnionStruct->EMVTradeParam->GenerateACRetDataLen;

    #ifdef EMVB_DEBUG
    emvb_printf("\r\n Paypassb_CombineDDASignVerify:%d",index);
    for(k = 0;k < index;k++)
    {
        emvb_printf("%02x ",SDAToSign[k]);
    }
    emvb_printf("");
    #endif

    //Hash(SDAToSign,index,SDAHash);
    tempApp_UnionStruct->emv_arith_hash(SDAToSign, index, SDAHash, 0);

    emvblib_free(SDAToSign);

    if(memcmp(ICCDynDataSign.HashResult,SDAHash,20))
    {
        #ifdef EMVB_DEBUG
        emvb_printf("\r\n Paypassb_CombineDDASignVerify120");
        #endif
        return EMV_ERR;
    }


    //
    if(cdatype == 1||cdatype == 3)
    {
        memset(tempbuf,0,sizeof(tempbuf));
        dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_TerminalRelayEntropy,tempbuf,0,4);
        if(memcmp(tempbuf,ICCDynDataSign.TerminalRelayEntropyCDA,4))
        {
            return EMV_ERR;
        }


        memset(tempbuf,0,sizeof(tempbuf));
        dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_DeviceRelayEntropy,tempbuf,0,4);
        if(memcmp(tempbuf,ICCDynDataSign.DeviceRelayEntropyCDA,4))
        {
            return EMV_ERR;
        }

        memset(tempbuf,0,sizeof(tempbuf));
        dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_MinTimeForRelay,tempbuf,0,2);
        if(memcmp(tempbuf,ICCDynDataSign.MintimeforRelayAPDUCDA,2))
        {
            return EMV_ERR;
        }

        memset(tempbuf,0,sizeof(tempbuf));
        dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_MaxTimeForRelay,tempbuf,0,2);
        if(memcmp(tempbuf,ICCDynDataSign.MaxtimeforRelayAPDUCDA,2))
        {
            return EMV_ERR;
        }

        memset(tempbuf,0,sizeof(tempbuf));
        dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_DEVEstimatedTimeForRelay,tempbuf,0,2);
        if(memcmp(tempbuf,ICCDynDataSign.DevEstTransTimeForRelayCDA,2))
        {
            return EMV_ERR;
        }




    }


    dllemvb_avl_createsettagvalue((unsigned char *)TAG_ICCDynNum,ICCDynDataSign.ICCDynNum,ICCDynDataSign.ICCDynNumLen);
    dllemvb_avl_createsettagvalue((unsigned char *)TAG_AppCrypt,ICCDynDataSign.AppCrypt,8);


    if(ICCDynDataSign.DSSummary2len)
    {
        dllemvb_avl_createsettagvalue((unsigned char *)TAG_DSSummary2,ICCDynDataSign.DSSummary2,ICCDynDataSign.DSSummary2len);
    }


    if(ICCDynDataSign.DSSummary3len)
    {
        dllemvb_avl_createsettagvalue((unsigned char *)TAG_DSSummary3,ICCDynDataSign.DSSummary3,ICCDynDataSign.DSSummary3len);
    }



    //S910.8
    if(cdatype == 1||cdatype == 2)
    {
        SignDynAppDataitem = dllemvb_avl_gettagitempointer((unsigned char *)TAG_DSSummary1);
        if(SignDynAppDataitem == NULL)
        {
            return PAYPASSIDSREADERROR;
        }

        //GAC -response 2  //sx?2017
        if(tempApp_UnionStruct->EMVTradeParam->paypassgacresponsetype == 1)
        {
            if(tempApp_UnionStruct->EMVTradeParam->IDSStatusInTorn&0x40)
            {
                if(tempApp_UnionStruct->EMVTradeParam->DSSummary1LenInTorn!= SignDynAppDataitem->len)
                {
                    return PAYPASSIDSREADERROR;
                }

                if(memcmp(tempApp_UnionStruct->EMVTradeParam->DSSummary1InTorn,SignDynAppDataitem->data,SignDynAppDataitem->len))
                {
                    return PAYPASSIDSREADERROR;
                }
            }
        }


        DOLDataitem = dllemvb_avl_gettagitempointer((unsigned char *)TAG_DSSummary2);
        if(DOLDataitem == NULL)
        {
            return PAYPASS_CARDDATAMISSING;
        }



        if(DOLDataitem->len != SignDynAppDataitem->len)
        {
            return PAYPASSIDSREADERROR;
        }

        if(memcmp(DOLDataitem->data,SignDynAppDataitem->data,DOLDataitem->len))
        {
            return PAYPASSIDSREADERROR;
        }


        //S910.12  success read
        dllemvb_avl_setvalue_or((unsigned char *)TAG_DSSummaryStatus,0,0x80);


        //S910.13  IDS Write Flag set
        if(dllemvb_avl_gettagvalue((unsigned char *)TAG_IDSStatus)&0x40)
        {
            //S910.14
            SignDynAppDataitem = dllemvb_avl_gettagitempointer((unsigned char *)TAG_DSSummary3);
            if(SignDynAppDataitem == NULL)
            {
                return PAYPASS_CARDDATAMISSING;
            }

            if(DOLDataitem->len != SignDynAppDataitem->len)
            {
                dllemvb_avl_setvalue_or((unsigned char *)TAG_DSSummaryStatus,0,0x40);
                return EMV_OK;
            }

            if(memcmp(DOLDataitem->data,SignDynAppDataitem->data,DOLDataitem->len))
            {
                dllemvb_avl_setvalue_or((unsigned char *)TAG_DSSummaryStatus,0,0x40);
                return EMV_OK;
            }


            //S910.18
            if(dllemvb_avl_gettagvalue((unsigned char *)TAG_DSODSInfoReader)&0x02)
            {
                return PAYPASSIDSWRITEERR;
            }


        }


    }

    return EMV_OK;

}

/*******************************************************************
��    ��:
��������: unsigned char Paypassb_CombineDDA(unsigned char type,AppUnionStruct *tempApp_UnionStruct)
��������: ����������֤
��ڲ���: ��
�� �� ֵ: ��
��ص���:
��    ע:
�޸���Ϣ:   20130731
********************************************************************/
unsigned char Paypassb_CombineDDA(unsigned char type,EMVBAppUnionStruct *tempApp_UnionStruct)
{
    unsigned char retCode;

    if(tempApp_UnionStruct->EMVTradeParam->ODASMstaus)
    {
        //retCode=SM_CombineDDASignVerify(type,tempApp_UnionStruct);
        retCode = EMV_ERR;
    }
    else
    {
        retCode=Paypassb_CombineDDASignVerify(type,tempApp_UnionStruct);
    }

    if(retCode!=EMV_OK) //Dynamic Signature Verification
    {
        #ifdef EMVB_DEBUG
        emvb_printf("\nDynanic sign verify ERR");
        #endif
        return retCode;
    }

    return EMV_OK;
}


/*******************************************************************
×÷    Õß:
º¯ÊýÃû³Æ: unsigned char paypasscdadeal(AppUnionStruct *tempApp_UnionStruct)
º¯Êý¹¦ÄÜ: paypass ¸´ºÏÊý¾ÝÈÏÖ¤
Èë¿Ú²ÎÊý: ÎÞ
·µ »Ø Öµ: ÎÞ
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:    20140222
********************************************************************/
unsigned char paypassbcdadeal(EMVBAppUnionStruct *tempApp_UnionStruct)
{
    unsigned char retCode,ReferenceControlParameter;
	unsigned char CryptInfo,reqCrpt,TVR[5];
	
	CryptInfo =dllemvb_avl_gettagvalue((unsigned char *)TAG_CryptInfo);
    ReferenceControlParameter = dllemvb_avl_gettagvalue((unsigned char *)TAG_ReferenceControlParameter);
	reqCrpt = ReferenceControlParameter;
    //S910 CDA
	if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_SignDynAppData)&&(ReferenceControlParameter&0x10))
	{
		if(Paypassb_CombineDDA_FirstHalf(tempApp_UnionStruct)!=EMV_OK)     //Get CAPK,IPK,ICCPK //¸´ºÏ¶¯Ì¬ÈÏÖ¤ÏÈÈ¡µÃCAPK£¬IPK£¬ICCPK.
		{	
			dllemvb_avl_setvalue_or((unsigned char *)TAG_TVR,0,0x04);
			return EMV_OK;
		}
		
		#ifdef EMVB_DEBUG
        emvb_printf("\r\npaypassbcdadeal 1\r\n");
		#endif
			
		retCode=Paypassb_CombineDDA(GenerateAC1,tempApp_UnionStruct);
		#ifdef EMVB_DEBUG
        emvb_printf("\r\npaypassbcdadeal retCode = %d\r\n",retCode);
		#endif
		if(retCode == PAYPASS_CARDDATAMISSING||retCode == PAYPASS_CARDDATAERR||retCode == PAYPASSIDSWRITEERR
			||retCode == PAYPASSIDSREADERROR)
		{
			return retCode;
		}
		else if(retCode!=EMV_OK)
		{
			#ifdef TEMPTEST
			emvb_printf("\r\n Comes to CDA ERR1 \r\n");
			#endif
            
	    	dllemvb_avl_setvalue_or((unsigned char *)TAG_TVR,0,0x04);
			return EMV_OK;
		}
		
	}
	else
	{
		//S910 NO CDA 
		if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_AppCrypt)==0)
		{
			return PAYPASS_CARDDATAMISSING;
		}

		if((CryptInfo&0xc0) == 0x00) //AAC
		{
		    //S910.33
		    if(dllemvb_avl_gettagvalue((unsigned char *)TAG_IDSStatus)&0x80)
		    {
		    	
				return PAYPASS_CARDDATAERR;
				
		    }
			else
			{
				if((reqCrpt&0xC0) == 0x00)
				{
					if(reqCrpt&0x10)
					{
						return PAYPASS_CARDDATAERR;
					}
				}
			}
		}
		else
		{
			if(reqCrpt&0x10)
			{
				return PAYPASS_CARDDATAERR;
			}
			
			
			//S910.38
			gEmvballocator.EMVBallocator_memset(TVR,0,sizeof(TVR));
			dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_TVR,TVR,0,5);
			if((TVR[4]&0x03) == 0x02)  //RRP performed
			{
				 paypassb_storerelayresistantdata(tempApp_UnionStruct);
			}
			
			
			
		}
	        
		    
		
	}

	return EMV_OK;
}


/*******************************************************************
×÷    Õß:
º¯ÊýÃû³Æ: unsigned char Paypass_TransProcess(AppUnionStruct *tempApp_UnionStruct)
º¯Êý¹¦ÄÜ: PAYPASSÖÕ¶Ë½»Ò×´¦Àí
Èë¿Ú²ÎÊý:
·µ »Ø Öµ:
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:   20140222
********************************************************************/
unsigned char Paypassb_TransProcess(EMVBAppUnionStruct *tempApp_UnionStruct)     //½»Ò×´¦ÀíÁ÷³Ì
{
    unsigned char retCode = EMV_OK;
    unsigned char CryptInfo;
	unsigned char TVR[5];
	unsigned char POSCII[3];
    PHONEMESSAGETABLEINFO *tempphonemsgtbl;
	unsigned char j;
	unsigned char status = 0;
	unsigned char TransTypeValue;
	unsigned short FormFactIndicatorlen;
	unsigned char TermCapab[3],FormFactIndicator[32];
	unsigned char ReferenceControlParameter;
	unsigned char removecardflag = 0;
    
	tempphonemsgtbl = tempApp_UnionStruct->pphonemsgtable;
	
	
	CryptInfo =dllemvb_avl_gettagvalue((unsigned char *)TAG_CryptInfo);
	
	if((CryptInfo&0xC0)==0x00)//ICC return AAC,refuse the transaction.	
	{
		tempApp_UnionStruct->EMVTradeParam->TransResult=OFFLINE_DECLINE;
        
	}
	else if( (CryptInfo&0xC0)==0x40)//ICC return TC,approve the trans executed offline //lechan 090714
	{
		tempApp_UnionStruct->EMVTradeParam->TransResult=OFFLINE_APPROVE;	
	}
	else if( (CryptInfo&0xC0)==0x80)//ICC return TC,approve the trans executed offline //lechan 090714
	{
		tempApp_UnionStruct->EMVTradeParam->TransResult=ONLINE_WAIT;	
	}
    else 
    {
    	return EMV_ERR;
    }

	ReferenceControlParameter = dllemvb_avl_gettagvalue((unsigned char *)TAG_ReferenceControlParameter);
	retCode = paypassbcdadeal(tempApp_UnionStruct);
    if(retCode == PAYPASS_CARDDATAMISSING||retCode == PAYPASS_CARDDATAERR || retCode == PAYPASSIDSREADERROR)
    {
        if(retCode == PAYPASS_CARDDATAMISSING)
        {
        	Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S10_E22_0);
        }
		else if(retCode == PAYPASSIDSREADERROR)
		{
			Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S10_11);
		}
		else
		{
			Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S10_E24_0);
		}
		 //S910 Invalid response - 1
        Paypassb_Invalidresponse(tempApp_UnionStruct);
		#if 0
		Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S10_E50_0);
		if(dllemvb_avl_gettagvalue((unsigned char *)TAG_IDSStatus)&0x40)
		{
			Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S10_E52_0);
		}
		else
		{
			Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S11_E95_0);
		}
		#endif
			
    	return PAYPASS_ENDAPPLICATION;
    }
	else if(retCode == PAYPASSIDSWRITEERR)
	{
	    Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S10_E19_0);
		Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S11_101);
		return PAYPASS_ENDAPPLICATION;
	}
	
	
    if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_SignDynAppData)&&(ReferenceControlParameter&0x10))  //check if do CDA faile
    {
        gEmvballocator.EMVBallocator_memset(TVR,0,sizeof(TVR));
		dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_TVR,TVR,0,5);
    	if(TVR[0]&0x04)
    	{
    	   
    		Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S11_E46_0);
			 //S910 Invalid response - 1
			 Paypassb_Invalidresponse(tempApp_UnionStruct);
			 #if 0
			Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S11_E90_0);
			if(dllemvb_avl_gettagvalue((unsigned char *)TAG_IDSStatus)&0x40)
			{
				Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S10_E52_0);
			}
			else
			{
				Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S11_E95_0);
			}
			#endif
			return PAYPASS_ENDAPPLICATION;
    	}
    }

    //S910.70
	Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S11_E110_0);

    gEmvballocator.EMVBallocator_memset(POSCII,0,sizeof(POSCII));
	dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_POSCII,POSCII,0,3);
	
    #ifdef EMVB_DEBUG
    emvb_printf("\r\npaypass_dataauthaftergac 115 %02x %02x\r\n",POSCII[1],POSCII[2]);
    #endif
	//S11.111   S910.71  
	if((POSCII[1]&0x03)||(POSCII[2]&0x0F))
	{
	    //S11.112   S910.72
		Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S11_E112_0);
		//S910.73
		for(j =0;j < tempphonemsgtbl->phonemessagetablenum;j++)
		{
			if((POSCII[0]&tempphonemsgtbl->phonemessagetable[j].PCIIMASK[0]) == tempphonemsgtbl->phonemessagetable[j].PCIIVALUE[0]&&
				(POSCII[1]&tempphonemsgtbl->phonemessagetable[j].PCIIMASK[1]) == tempphonemsgtbl->phonemessagetable[j].PCIIVALUE[1]&&
				(POSCII[2]&tempphonemsgtbl->phonemessagetable[j].PCIIMASK[2]) == tempphonemsgtbl->phonemessagetable[j].PCIIVALUE[2])  //messge id messege status 
			{
				tempApp_UnionStruct->EMVTradeParam->PaypassSelectedPOSCIIID = j;
				Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S11_E113_0);
				break;
			}
		}
		
        status = 6;
	}
	else
	{
	    //OFFLINE approved  S11.114
		if(tempApp_UnionStruct->EMVTradeParam->TransResult == OFFLINE_APPROVE)
		{
			Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S11_E114_1);
		}
		else if(tempApp_UnionStruct->EMVTradeParam->TransResult == ONLINE_WAIT)
		{
			Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S11_E114_2);
		}
		else  //E74
		{
		    TransTypeValue = dllemvb_avl_gettagvalue((unsigned char *)TAG_TransTypeValue);
			if(TransTypeValue == 0x01||TransTypeValue == 0x17||TransTypeValue == 0x00||TransTypeValue == 0x09)
			{
			    Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S11_E115_2);
			    tempApp_UnionStruct->EMVTradeParam->TransResult = OFFLINE_DECLINE;

				gEmvballocator.EMVBallocator_memset(TermCapab,0,sizeof(TermCapab));
				dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_TermCapab,TermCapab,0,3);
                dllemvb_avl_gettagvalue_all((unsigned char *)TAG_PaypassThirdPartyData,FormFactIndicator,&FormFactIndicatorlen);
				#ifdef EMVB_DEBUG
                emvb_printf("\r\ndeclined data:%d %02x %02x %02x\r\n",FormFactIndicatorlen,FormFactIndicator[2],FormFactIndicator[4],FormFactIndicator[5]);
				#endif
				//S910.74
				if(((FormFactIndicatorlen>=6)&&((FormFactIndicator[2]&0x80)==0x00)&&(FormFactIndicator[4] != 0x30 ||FormFactIndicator[5] != 0x30))||
					((TermCapab[0]&0x20) == 0))
				{
				    
					Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S11_E114_3); //declined
				}
				else
				{
				    Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S11_E114_4); //try another interface
					status = 4;
				}
			}
			else   //END APPLICATION
			{
			    tempApp_UnionStruct->EMVTradeParam->TransResult = TERMINATE_TRANS_ERR;
				Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S11_E114_5);
				status = 5;  
				
			}
			
		}
	}

    
    if(status == 0)
    {
    	Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S11_E115_1);
		if(tempApp_UnionStruct->EMVTradeParam->TransResult == OFFLINE_APPROVE)
		{
			Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S11_E115_2);
			
			if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_BalanceAfterGAC))
			{
				Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S11_E115_3);
				if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_AppCurcyCode))
				{
					Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S11_E115_4);
				}
			}

			Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S11_E115_5);
		}
		else if(tempApp_UnionStruct->EMVTradeParam->TransResult == ONLINE_WAIT)
		{
			Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S11_E115_6);
		}
		else  //declined
		{
			Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S11_E115_7);
		}
		
		status = 6;
    }
	
    
	if(status == 4)
	{
		Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S11_E115_1);
        Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S11_E115_8);
		status = 6;
	}

    if(status == 5)
    {
    	Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S11_E115_1);
        Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S11_E115_9);
		status = 6;
    }

	
	//S11.116  Post Gen AC PUT DATA
	if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_WriteAfterGAC))
	{
		removecardflag = 1;
	}
	Paypassb_PostGENACPUTDATA(tempApp_UnionStruct);
	

	
    if(status == 6)
	{
		//S910.78.1
        if((POSCII[1]&0x03)||(POSCII[2]&0x0F))
        {
            //S910.79
            if(removecardflag)
            {
            	Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S15_10);
            }
			else
			{
            	Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S11_E119_0);
			}
        	Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S11_E120_1);
        }
		else
		{
		    if(removecardflag)
		    {
		    	Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S15_12);
		    }
			else
			{
				//Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S11_E120_2);
			}
			Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S11_E120_2);  // try another interface µÄ?
		}

		return EMV_OK;
	}
					
	return retCode;
}

/*******************************************************************
×÷    Õß:
º¯ÊýÃû³Æ: unsigned char Paypassb_OnLineDeal(EMVBAppUnionStruct *tempApp_UnionStruct)
º¯Êý¹¦ÄÜ: Áª»ú³É¹¦ºóÊý¾Ý´¦Àí
Èë¿Ú²ÎÊý:
·µ »Ø Öµ:
Ïà¹Øµ÷ÓÃ:
±¸    ×¢:
ÐÞ¸ÄÐÅÏ¢:  20140222
********************************************************************/
unsigned char Paypassb_OnLineDeal(EMVBAppUnionStruct *tempApp_UnionStruct)
{

	unsigned char AuthRespCode[2];
    
    
	gEmvballocator.EMVBallocator_memset(AuthRespCode,0,sizeof(AuthRespCode));
	dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AuthRespCode,AuthRespCode,0,2);
    #ifdef EMVB_DEBUG
	emvb_printf("This is OnOnLineDeal AuthRespCode=%02X %02X \r\n", AuthRespCode[0], AuthRespCode[1]);
	#endif

	if(!gEmvballocator.EMVBallocator_memcmp(AuthRespCode,"00",2) || 
		!gEmvballocator.EMVBallocator_memcmp(AuthRespCode,"10",2) ||
		!gEmvballocator.EMVBallocator_memcmp(AuthRespCode,"11",2) )//Issuer approval,according to p172 of VIS140 terminal specification.
	{
		//Èç¹û·¢¿¨ÐÐÅú×¼½»Ò×(ÊÚÈ¨ÏìÓ¦ÂëÎª'00','10','11')Ê±,ÖÕ¶ËÇëÇóTC
		tempApp_UnionStruct->EMVTradeParam->TransResult = ONLINE_APPROVE;
	}
	else if(!gEmvballocator.EMVBallocator_memcmp(AuthRespCode,"01",2) ||
		!gEmvballocator.EMVBallocator_memcmp(AuthRespCode,"02",2))//Issuer referral  
	{
		//Èç¹û·¢¿¨ÐÐÇëÇó²Î¿¼(ÊÚÈ¨ÏìÓ¦ÂëÎª'01','02')Ê±,
		//ÖÕ¶ËÌáÊ¾²Ù×÷Ô±´òµç»°ÊÚÈ¨,¸ù¾Ý·¢¿¨ÐÐÊÚÈ¨½á¹û(Åú×¼»ò¾Ü¾ø)
		//À´ÇëÇóÏàÓ¦µÄÃÜÎÄ.Èç¹ûÖÕ¶Ë²»Ö§³Ö²Î¿¼,ÔòÖÕ¶ËÇëÇóAAC
		tempApp_UnionStruct->EMVTradeParam->IfNeedRefer =1;
		return EMV_ERR;
	}
	else//Other codes are looked as Issuer decline.
	{	//Èç¹ûÊÚÈ¨ÂëÎ´Ö¸Ã÷Åú×¼»ò²Î¿¼,ÔòÖÕ¶ËÇëÇóAAC.
		tempApp_UnionStruct->EMVTradeParam->TransResult = ONLINE_DECLINE;
	}
	return EMV_OK;
}



void Paypassb_CheckAUC(EMVBAppUnionStruct *tempApp_UnionStruct)
{
	unsigned char bTestFail;
    unsigned char TermType,AUC[2],AUCbExist;
	unsigned char IssuCountryCode[2],CountryCode[2],IssuCountryCodebExist;
	unsigned char TermAmtOther[6];
    unsigned char TermAddCapab[5];
	unsigned char TermAmtOtherBin = 0;
	//unsigned char TransType;
	unsigned char TransTypeValue;
	

	#ifdef EMVB_DEBUG
    emvb_printf("\r\nEmvb_CheckAUC\r\n");
	#endif
	bTestFail=0;
	gEmvballocator.EMVBallocator_memset(AUC,0,sizeof(AUC));
    AUCbExist = !(dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AUC,AUC,0,2));
    
	TermType = dllemvb_avl_gettagvalue((unsigned char *)TAG_TermType);
	//TransType = tempApp_UnionStruct->EMVTradeParam->TransType;  //TransTypeÓÐÃ»ÓÐ¶¨Òå

    
	TransTypeValue = dllemvb_avl_gettagvalue((unsigned char *)TAG_TransTypeValue);

	
	gEmvballocator.EMVBallocator_memset(TermAddCapab,0,sizeof(TermAddCapab));
	dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_TermAddCapab,TermAddCapab,0,5);
    
    gEmvballocator.EMVBallocator_memset(IssuCountryCode,0,sizeof(IssuCountryCode));
	IssuCountryCodebExist = !(dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_IssuCountryCode,IssuCountryCode,0,2));
    gEmvballocator.EMVBallocator_memset(CountryCode,0,sizeof(CountryCode));
	dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_CountryCode,CountryCode,0,2);
    
    
	gEmvballocator.EMVBallocator_memset(TermAmtOther,0,sizeof(TermAmtOther));
    dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AmtOtherNum,TermAmtOther,0,6);
	if(gEmvballocator.EMVBallocator_memcmp(TermAmtOther,"\x00\x00\x00\x00\x00\x00",6))
	{
		TermAmtOtherBin = 1;
	}
    
    
	
	if(AUCbExist)//AUC exist.
	{
		if((TermType==0x14 || TermType==0x15 || TermType==0x16 )
			&& (TermAddCapab[0]&0x80))//The termianl is ATM
		{
			if(!(AUC[0]&0x02))// if¡®Valid at ATMs¡¯bit not on.
				bTestFail=1;
		}
		else//The terminal is not ATM
		{
			if(!(AUC[0]&0x01))// if¡®Valid at terminals other than ATMs¡¯bit not on.
				bTestFail=1;
		}
		if(IssuCountryCodebExist){//Issuer country code exist
			if(!gEmvballocator.EMVBallocator_memcmp(IssuCountryCode,CountryCode,2))//domestic
			{
				if(TransTypeValue==0x01||TransTypeValue==0x17)
				{
					if(!(AUC[0]&0x80))// if¡®Valid for domestic cash transactions¡¯bit not on.
						bTestFail=1;
				}
				
				if(TransTypeValue==0x00||TransTypeValue==0x09 )
				{
					if( !(AUC[0]&0x28))// if¡®Valid for domestic goods and service¡¯bit not on.
						bTestFail=1;	
				}
				if(TermAmtOtherBin!=0)    //&& TransType==CASHBACK
				{
					if(!(AUC[1]&0x80))// if¡®domestic cashback allowed¡¯bit not on.
						bTestFail=1;
				}
			}
			else//international,terminal country code differ from issuer country code
			{
				if(TransTypeValue==0x01||TransTypeValue==0x17)
				{
					if(!(AUC[0]&0x40))// if¡®Valid for international cash transactions¡¯bit not on.
						bTestFail=1;
				}
				
				if(TransTypeValue==0x00||TransTypeValue==0x09)
				{
					if( !(AUC[0]&0x14))// if¡®Valid for domestic goods and service¡¯bit not on.
						bTestFail=1;
				}
				
				if(TermAmtOtherBin!=0 )  //TransType==CASHBACK  && dllemvb
				{
					if(!(AUC[1]&0x40))// if¡®international cashback allowed¡¯bit not on.
						bTestFail=1;
				}
			}
		}
	}
    
	
	if(bTestFail)
	{
		dllemvb_avl_setvalue_or((unsigned char *)TAG_TVR,1,0x10);//set¡®Requested service not allowed for card product¡¯bit 1
	}
    
	
	#ifdef EMVB_DEBUG
    dllemvb_avl_printtagallvalue((unsigned char *)"TVR",(unsigned char *)TAG_TVR);
	#endif
	
}


/*******************************************************************
��    ��:
��������: void Paypassb_CheckVer(AppUnionStruct *tempApp_UnionStruct)
��������: �жϰ汾�Ƿ�һ��
��ڲ���: ��
�� �� ֵ: ��.
��ص���:
��    ע:
�޸���Ϣ:        20130731
********************************************************************/
void Paypassb_CheckVer(EMVBAppUnionStruct *tempApp_UnionStruct)
{

    unsigned char CardAppVerbExist;
    unsigned char TermAppVerbExist;
    EMVTAGCVLITEM *Termitem = NULL,*Carditem = NULL;

    #ifdef EMVB_DEBUG
    emvb_printf("\r\n Paypassb_CheckVer");
    #endif


    Carditem = dllemvb_avl_gettagitempointerandexiststatus((unsigned char *)TAG_AppVerNum,&CardAppVerbExist);
    Termitem = dllemvb_avl_gettagitempointerandexiststatus((unsigned char *)TAG_AppVer,&TermAppVerbExist);

    #ifdef EMVB_DEBUG
    emvb_printf("\r\n Paypassb_CheckVer 1 %d %d",CardAppVerbExist,TermAppVerbExist);
    #endif
    if(CardAppVerbExist&&TermAppVerbExist)
    {
        if(Carditem->len != Termitem->len)
        {
            dllemvb_avl_setvalue_or((unsigned char *)TAG_TVR,1,0x80);
        }
        else
        {
            if(memcmp(Carditem->data,Termitem->data,Termitem->len))
            {
                dllemvb_avl_setvalue_or((unsigned char *)TAG_TVR,1,0x80);
            }
        }
    }

    #ifdef EMVB_DEBUG
    emvb_printf("\r\n Paypassb_CheckVer2");
    #endif

}


/*******************************************************************
��    ��:
��������: unsigned char Paypassb_CheckExpDate(AppUnionStruct *tempApp_UnionStruct)
��������: �жϿ�Ƭ��Ч����
��ڲ���: ��
�� �� ֵ: OK ��Ч.
          ERR ��Ч.
��ص���:
��    ע:
�޸���Ϣ:   20130731
********************************************************************/
unsigned char Paypassb_CheckExpDate(EMVBAppUnionStruct *tempApp_UnionStruct)
{
    unsigned char currentDate[4],EffectDate[4],ExpireDate[4];  //buf[10],
    unsigned char AppEffectDateexist,AppExpireDateexist;
    EMVTAGCVLITEM *item;


    #ifdef EMVB_DEBUG
    emvb_printf("\r\n Paypassb_CheckExpDate");
    #endif

    dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_TransDate,&currentDate[1],0,3);


    if(currentDate[1]>0x49) currentDate[0]=0x19;
    else currentDate[0]=0x20;

    AppEffectDateexist = 0;
    item = dllemvb_avl_gettagitempointer((unsigned char *)TAG_AppEffectDate);
    if(item != NULL)
    {
        if(item->len>=3)
        {
            AppEffectDateexist = 1;
        }
    }



    if(AppEffectDateexist)//App effective date exist
    {


        if(item->data[0]>0x49) EffectDate[0]=0x19;
        else EffectDate[0]=0x20;

        memcpy((unsigned char*)&EffectDate[1],item->data,3);

        if(Emv_CheckDateFormat(EffectDate)==EMV_ERR) return EMV_ERR;

        if(memcmp(currentDate,EffectDate,4)<0)
        {
            dllemvb_avl_setvalue_or((unsigned char *)TAG_TVR,1,0x20);
        }
    }

    AppExpireDateexist = 0;
    item = dllemvb_avl_gettagitempointer((unsigned char *)TAG_AppExpireDate);
    if(item != NULL)
    {
        if(item->len>=3)
        {
            AppExpireDateexist = 1;
        }
    }

    if(AppExpireDateexist)//App expiration date exist
    {
        //if(Emv_CheckDateFormat(item->data)==EMV_ERR) return EMV_ERR;

        if(item->data[0]>0x49) ExpireDate[0]=0x19;
        else ExpireDate[0]=0x20;

        memcpy((unsigned char*)&ExpireDate[1],item->data,3);
        if(Emv_CheckDateFormat(ExpireDate)==EMV_ERR) return EMV_ERR;
        if(memcmp(currentDate,ExpireDate,4)>0)
        {
            dllemvb_avl_setvalue_or((unsigned char *)TAG_TVR,1,0x40);
        }
    }
    return EMV_OK;

}



//?20150724»¹Ã»ÓÐÐÞ¸Ä
unsigned char Paypassb_ProcessRestrict(EMVBAppUnionStruct *tempApp_UnionStruct)
{
    
	Paypassb_CheckVer(tempApp_UnionStruct);
	Paypassb_CheckAUC(tempApp_UnionStruct);  //sxl?2022要看一下是否正确
	if(Paypassb_CheckExpDate(tempApp_UnionStruct)!=EMV_OK) return EMV_ERR;
	return EMV_OK;
	
}




unsigned char paypassb_SendDEKSignal(EMVBAppUnionStruct *tempApp_UnionStruct,unsigned int step,APDU_SEND *apdu_s)
{
	return tempApp_UnionStruct->paypasssendDEK((uintptr_t)tempApp_UnionStruct,step,apdu_s);
}




void paypassb_command_exchangerelaydata(APDU_SEND *apdu_s,unsigned char *Entropy)
{
   
    gEmvballocator.EMVBallocator_memcpy(apdu_s->Command,"\x80\xEA\x00\x00",4);  
	
	apdu_s->Lc = 4;
    gEmvballocator.EMVBallocator_memcpy(apdu_s->DataIn,Entropy,4);
	apdu_s->Le=256;
	apdu_s->EnableCancel = 1;       //Ê¹ÄÜ°´È¡Ïû¼ü

}


unsigned char Paypassb_RRP(EMVBAppUnionStruct *tempApp_UnionStruct)
{
	
    //unsigned char retCode;
	unsigned char AIP[2];
	unsigned char Kernelconfig;
	unsigned char Entropy[4];
	APDU_SEND apdu_s;
	APDU_RESP apdu_r;
	unsigned long long timerstarttick,timerendtick;
	int devrelayrapdu,terrelayrpadu,mindelayrapdu;
	int relaycapdu;
	int minimumforrelay,minimumrelayperiod;
	int maximumforrelay,maximumrelayperiod;
	int relaymismatchthreahold;
	int relayAccuracythreshold;
	int processtime;
	unsigned char temp[2];
	unsigned char rrpcounter;
	unsigned short index,lenTemp;
	int tmpvalue;

	Kernelconfig = dllemvb_avl_gettagvalue((unsigned char *)TAG_KernelConfiguration);
    gEmvballocator.EMVBallocator_memset(AIP,0,sizeof(AIP));
	dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AIP,AIP,0,2);
	
    if((Kernelconfig&0x10)&&(AIP[1]&0x01))  //support RRP
    {
    	while(1)
    	{
	        //S3.61
	        tempApp_UnionStruct->EMVB_RandomNum(Entropy,4);
	    	dllemvb_avl_createsettagvalue((unsigned char *)TAG_UnpredictNum,Entropy,4);
			dllemvb_avl_createsettagvalue((unsigned char *)TAG_TerminalRelayEntropy,Entropy,4);
			//S3.62
			paypassb_command_exchangerelaydata(&apdu_s,Entropy);
			//S3.63
			timerstarttick = tempApp_UnionStruct->user_gettimetick();//us
			//S3.64
			tempApp_UnionStruct->EMVB_qPBOCIccIsoCommand(&apdu_s,&apdu_r);
            timerendtick = tempApp_UnionStruct->user_gettimetick(); //us
            #ifdef ZTPAYPASS_DEBUG
			emvb_printf("apdu_r.ReadCardDataOk = %d",apdu_r.ReadCardDataOk);
			#endif
			if(apdu_r.ReadCardDataOk != EMV_OK)
		    {
				// PPSE STOP
		    	if(tempApp_UnionStruct->EmvErrID->L3 != EMVB_ERRID_L3_STOP)
		        {
		            Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_SR1_5_1);
		        	Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_SR1_5_2);
		        }
				// PPSE STOP
		    	return ERR_APP_TIMEOUT;
		    }
			
	        if(!(apdu_r.SWA == 0x90&&apdu_r.SWB == 0x00))
	        {
	        	Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_SR1_12);
				Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_SR1_13);
				return PAYPASS_ENDAPPLICATION;
	        }

			
           
			
			//SR1.14
			if(apdu_r.LenOut>11&&apdu_r.DataOut[0]==0x80)  //&&apdu_r.DataOut[1]==10
			{
			    index = 1;
				lenTemp= 0;
			    ParseExtLen(apdu_r.DataOut,&index,&lenTemp);
				if(lenTemp == 10)
				{
					dllemvb_avl_createsettagvalue((unsigned char *)TAG_DeviceRelayEntropy,&apdu_r.DataOut[index],4);
					dllemvb_avl_createsettagvalue((unsigned char *)TAG_MinTimeForRelay,&apdu_r.DataOut[index+4],2);
					dllemvb_avl_createsettagvalue((unsigned char *)TAG_MaxTimeForRelay,&apdu_r.DataOut[index+6],2);
					dllemvb_avl_createsettagvalue((unsigned char *)TAG_DEVEstimatedTimeForRelay,&apdu_r.DataOut[index+8],2);
				}
				else
				{
					Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_SR1_16);
					Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_SR1_17);
					return PAYPASS_ENDAPPLICATION;
				}
			}
	        else  //parse error
	        {
	        	
	        	Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_SR1_16);
				Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_SR1_17);
				return PAYPASS_ENDAPPLICATION;
	        }
			
			
			//SR1.18
			timerendtick -= timerstarttick; //us
			timerendtick = timerendtick/100;  //100 Î¢Ãî



			gEmvballocator.EMVBallocator_memset(temp,0,sizeof(temp));
			dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_TermExpectTimeForRelayC,temp,0,2);
			relaycapdu = temp[0];
			relaycapdu = (relaycapdu<<8) + temp[1];
			
			gEmvballocator.EMVBallocator_memset(temp,0,sizeof(temp));
	        dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_TermExpectTimeForRelayR,temp,0,2);
			terrelayrpadu = temp[0];
			terrelayrpadu = (terrelayrpadu<<8) + temp[1];

			
			gEmvballocator.EMVBallocator_memset(temp,0,sizeof(temp));
	        dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_DEVEstimatedTimeForRelay,temp,0,2);
			devrelayrapdu = temp[0];
			devrelayrapdu = (devrelayrapdu<<8) + temp[1];

			//printf("devrelayrapdu = %d \r\n", devrelayrapdu);
	        if(devrelayrapdu > terrelayrpadu)
	        {
				mindelayrapdu = terrelayrpadu;
	        }
			else
			{
				mindelayrapdu = devrelayrapdu;
			}

	        //printf("processtime = %ld %d %d \r\n",timerendtick, relaycapdu, mindelayrapdu);

			processtime = timerendtick - relaycapdu - mindelayrapdu;
			if(processtime < 0)
			{
			    processtime = 0;
			}
			temp[0] = (unsigned char)(processtime>>8);
            temp[1] = (unsigned char)(processtime);
			dllemvb_avl_createsettagvalue((unsigned char *)TAG_MeasuredRelayProcessTime,temp,2);

			//SR1.19
			gEmvballocator.EMVBallocator_memset(temp,0,sizeof(temp));
	        dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_MinTimeForRelay,temp,0,2);
			minimumforrelay = temp[0];
			minimumforrelay = (minimumforrelay<<8) + temp[1];

			
			gEmvballocator.EMVBallocator_memset(temp,0,sizeof(temp));
	        dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_MinimRelayPeriod,temp,0,2);
			minimumrelayperiod = temp[0];
			minimumrelayperiod = (minimumrelayperiod<<8) + temp[1];
			tmpvalue = minimumforrelay - minimumrelayperiod;
			if(tmpvalue < 0)
			{
			    tmpvalue = 0;
			}

			//printf("tmpvalue = %d %d %d %d\r\n", processtime, tmpvalue, minimumforrelay, minimumrelayperiod);
	        if(processtime < tmpvalue)
	        {
	        	//SR1.20
	        	Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_SR1_20);
				Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_SR1_21);
				return PAYPASS_ENDAPPLICATION;
	        }

			
			gEmvballocator.EMVBallocator_memset(temp,0,sizeof(temp));
	        dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_MaxTimeForRelay,temp,0,2);
			maximumforrelay = temp[0];
			maximumforrelay = (maximumforrelay<<8) + temp[1];

			
			gEmvballocator.EMVBallocator_memset(temp,0,sizeof(temp));
	        dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_MaximRelayPeriod,temp,0,2);
			maximumrelayperiod = temp[0];
			maximumrelayperiod = (maximumrelayperiod<<8) + temp[1];

			rrpcounter = dllemvb_avl_gettagvalue((unsigned char *)TAG_RRPCounter);

			//printf("maximumforrelaykkk = %d %d %d \r\n",processtime, maximumforrelay, maximumrelayperiod);
			//SR1.22
			if(rrpcounter< 2 &&processtime>(maximumforrelay + maximumrelayperiod))
			{
			    //SR1.23
				//tempApp_UnionStruct->EMVB_RandomNum(Entropy,4);
		    	//dllemvb_avl_createsettagvalue((unsigned char *)TAG_UnpredictNum,Entropy,4);
				//dllemvb_avl_createsettagvalue((unsigned char *)TAG_TerminalRelayEntropy,Entropy,4);
				//Sr1.24
				dllemvb_avl_set((unsigned char *)TAG_RRPCounter,rrpcounter+1);
				continue;
				
			}

	        break;
		}
		

    	//printf("maximumforrelayppp = %d %d %d \r\n",processtime, maximumforrelay, maximumrelayperiod);
		//SR1.28
		if(processtime>(maximumforrelay + maximumrelayperiod))
		{
			
		    //SR1.29
			dllemvb_avl_setvalue_or((unsigned char *)TAG_TVR,4,0x04);
			
		}


		//printf("devrelayrapdu = %d %d \r\n",devrelayrapdu, terrelayrpadu);
        //SR1.30
		if(devrelayrapdu != 0 && terrelayrpadu != 0)
		{
		    //gEmvballocator.EMVBallocator_memset(temp,0,sizeof(temp));
            //dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_RelayMismatchThreshold,temp,0,2);
            relaymismatchthreahold = dllemvb_avl_gettagvalue((unsigned char *)TAG_RelayMismatchThreshold);
            if(relaymismatchthreahold == 0)
            {
                relaymismatchthreahold = 1;
            }
            //relaymismatchthreahold = (relaymismatchthreahold<<8) + temp[1];



            gEmvballocator.EMVBallocator_memset(temp,0,sizeof(temp));
            dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_RelayAccuracyThreshold,temp,0,2);
            relayAccuracythreshold = temp[0];
            relayAccuracythreshold = (relayAccuracythreshold<<8) + temp[1];

            tmpvalue = processtime - minimumforrelay;
            if(tmpvalue < 0)
            {
                tmpvalue = 0;
            }



            //printf("relaymismatchthreahold = %d %d \r\n",devrelayrapdu*100/terrelayrpadu, relaymismatchthreahold);
            //printf("11 = %d %d \r\n", terrelayrpadu*100/devrelayrapdu, relaymismatchthreahold);
            //printf("22 = %d %d \r\n", tmpvalue, relayAccuracythreshold);
            //SR1.30
            if((devrelayrapdu*100/terrelayrpadu) < relaymismatchthreahold||(terrelayrpadu*100/devrelayrapdu)<relaymismatchthreahold
                ||tmpvalue > relayAccuracythreshold)
            {
                //SR1.31
                dllemvb_avl_setvalue_or((unsigned char *)TAG_TVR,4,0x08);
            }
		}
		else  //SR1.31
        {
		    dllemvb_avl_setvalue_or((unsigned char *)TAG_TVR,4,0x08);
        }
#if 0
		else
		{
			
			//gEmvballocator.EMVBallocator_memset(temp,0,sizeof(temp));
	        //dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_RelayMismatchThreshold,temp,0,2);
			relaymismatchthreahold = dllemvb_avl_gettagvalue((unsigned char *)TAG_RelayMismatchThreshold);
			if(relaymismatchthreahold == 0)
			{
				relaymismatchthreahold = 1;
			}
			//relaymismatchthreahold = (relaymismatchthreahold<<8) + temp[1];
			
			

			gEmvballocator.EMVBallocator_memset(temp,0,sizeof(temp));
	        dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_RelayAccuracyThreshold,temp,0,2);
			relayAccuracythreshold = temp[0];
			relayAccuracythreshold = (relayAccuracythreshold<<8) + temp[1];
			
			//SR1.30
			if((devrelayrapdu*100/terrelayrpadu) < relaymismatchthreahold||(terrelayrpadu*100/devrelayrapdu)<relaymismatchthreahold
				||(processtime - minimumforrelay)>relayAccuracythreshold)
			{
				//SR1.31
				dllemvb_avl_setvalue_or((unsigned char *)TAG_TVR,4,0x08);
			}
            
        	
            
		}
#endif
		//SR1.32
    	dllemvb_avl_setvalue_and((unsigned char *)TAG_TVR,4,0xFC);
		dllemvb_avl_setvalue_or((unsigned char *)TAG_TVR,4,0x02);  //RRP performed
    }
	else
	{
		//S3.65
		dllemvb_avl_setvalue_and((unsigned char *)TAG_TVR,4,0xFC);
		dllemvb_avl_setvalue_or((unsigned char *)TAG_TVR,4,0x01);
        //TO S3R1
	}


	//S3R1
	
	
	
	

	return EMV_OK;
	
}

void paypassb_command_getdata(APDU_SEND *apdu_s,unsigned char *tag,unsigned char taglen)
{
   
    gEmvballocator.EMVBallocator_memcpy(apdu_s->Command,"\x80\xCA",2);  
	if(taglen == 2)
	{
    	gEmvballocator.EMVBallocator_memcpy(&apdu_s->Command[2],tag,2);
	}
	else
	{
		apdu_s->Command[2] = 0;
		apdu_s->Command[3] = tag[0];
	}
	
	apdu_s->Lc = 0;
	apdu_s->Le=256;
	apdu_s->EnableCancel = 1;       //Ê¹ÄÜ°´È¡Ïû¼ü

}

//Ö»ÔËÐÐÒ»´Î
unsigned char paypassb_idsprocess(EMVBAppUnionStruct *tempApp_UnionStruct)
{
    EMVTAGCVLITEM *emvitem;
	unsigned char tagexistflag;
	unsigned char dsslotnotempty = 0;
	unsigned char dssummary1notempty = 0;
	unsigned char dsUNnotempty = 0;
	unsigned char dsodscardpresent = 0;
    unsigned char AIP[2],TermCapab[3];

	if(tempApp_UnionStruct->EMVTradeParam->paypassidsrunflag)
	{
		return EMV_OK;
	}
			
    //S3R1.10
	if(dllemvb_avl_gettagvalue((unsigned char *)TAG_IDSStatus)&0x80)
	{
		//S3R1.11
		emvitem = dllemvb_avl_gettagitempointerandexiststatus((unsigned char *)TAG_DSSlotAvail,&tagexistflag);
		if(tagexistflag)
		{
		    dsslotnotempty = 1;
			Paypassb_AddDataToList_TLV((unsigned char *)TAG_DSSlotAvail,emvitem->data,emvitem->len,(unsigned char *)TAG_PaypassDataToSend);
		}

		emvitem = dllemvb_avl_gettagitempointerandexiststatus((unsigned char *)TAG_DSSummary1,&tagexistflag);
		if(tagexistflag)
		{
		    dssummary1notempty = 1;
			Paypassb_AddDataToList_TLV((unsigned char *)TAG_DSSummary1,emvitem->data,emvitem->len,(unsigned char *)TAG_PaypassDataToSend);
		}
		
		emvitem = dllemvb_avl_gettagitempointerandexiststatus((unsigned char *)TAG_DSUnpredictableNumber,&tagexistflag);
		if(tagexistflag)
		{
		    dsUNnotempty = 1;
			Paypassb_AddDataToList_TLV((unsigned char *)TAG_DSUnpredictableNumber,emvitem->data,emvitem->len,(unsigned char *)TAG_PaypassDataToSend);
		}
		
		emvitem = dllemvb_avl_gettagitempointerandexiststatus((unsigned char *)TAG_DSSlotManage,&tagexistflag);
		if(tagexistflag)
		{
			Paypassb_AddDataToList_TLV((unsigned char *)TAG_DSSlotManage,emvitem->data,emvitem->len,(unsigned char *)TAG_PaypassDataToSend);
		}

		emvitem = dllemvb_avl_gettagitempointer((unsigned char *)TAG_DSODSCard);
		if(emvitem != NULL)
		{
		    dsodscardpresent = 1;
			Paypassb_AddDataToList_TLV((unsigned char *)TAG_DSODSCard,emvitem->data,emvitem->len,(unsigned char *)TAG_PaypassDataToSend);
		}

		emvitem = dllemvb_avl_gettagitempointer((unsigned char *)TAG_UnpredictNum);
		if(emvitem != NULL)
		{
			Paypassb_AddDataToList_TLV((unsigned char *)TAG_UnpredictNum,emvitem->data,emvitem->len,(unsigned char *)TAG_PaypassDataToSend); //sx2017 Òª»¹Ô­²âÊÔÓÃ
			//Paypassb_AddDataToList_TLV((unsigned char *)TAG_UnpredictNum,"\xFF\xFF\xFF\xFF",4,(unsigned char *)TAG_PaypassDataToSend);
		}

		//S3R1.12
		if((dsslotnotempty&&dssummary1notempty&&dsUNnotempty&&dsodscardpresent==0)||(dssummary1notempty&&dsodscardpresent))  //continue with IDS 
		{
			
		}
		else
		{
			//S3R1.13
			dllemvb_avl_setvalue_and((unsigned char *)TAG_IDSStatus,0,0x7F);
		}
		
	}
	
	
    if(tempApp_UnionStruct->EMVTradeParam->qPBOCOrMSD == qPBOCTYPE)
    {
        //S3R1.14 
		Paypassb_AddTLVToList_RemoveTag((unsigned char *)TAG_PAYPSS_TAGSTOREADYET,(unsigned char *)TAG_PaypassDataToSend);
	    //S3R1.15
	    if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_PaypassDataNeeded)||(dllemvb_avl_checkiftagexist((unsigned char *)TAG_PaypassDataToSend)&&dllemvb_avl_checkiftagempty((unsigned char *)TAG_PAYPSS_TAGSTOREADYET)))
	    {
			//S3R1.16
	    	paypassb_SendDEKSignal(tempApp_UnionStruct,PAYPASSSTEP_S3_78,NULL);
	    }
	
        gEmvballocator.EMVBallocator_memset(AIP,0,sizeof(AIP));
		gEmvballocator.EMVBallocator_memset(TermCapab,0,sizeof(TermCapab));
	    dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_AIP,AIP,0,2);
		dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_TermCapab,TermCapab,0,3);
		//S3R1.17
		if((AIP[0]&0x01)&&(TermCapab[2]&0x08))
		{
			tempApp_UnionStruct->EMVTradeParam->ODAstaus = 1;
		}
		else
		{
		    if(dllemvb_avl_gettagvalue((unsigned char *)TAG_IDSStatus)&0x80) // IDS read flag set
		    {
		    	tempApp_UnionStruct->EMVTradeParam->ODAstaus = 1;
		    }
			else
			{
			    //S3R1.20
			    tempApp_UnionStruct->EMVTradeParam->ODAstaus = 0;
		    	dllemvb_avl_setvalue_or((unsigned char *)TAG_TVR,0,0x80);
			}
			
		}
    }

	tempApp_UnionStruct->EMVTradeParam->paypassidsrunflag = 1;
	return EMV_OK;
	
}


unsigned char paypassb_idsprocess_afterreadrecord(EMVBAppUnionStruct *tempApp_UnionStruct)
{
    
	unsigned char AppPAN[30],PANSeq;
    unsigned char tempbuf[60];
	unsigned short templen = 0,len = 0;
	EMVTAGCVLITEM *emvitem;
	
	if(tempApp_UnionStruct->EMVTradeParam->qPBOCOrMSD == qPBOCTYPE)
	{
		
		if(dllemvb_avl_gettagvalue((unsigned char *)TAG_IDSStatus)&0x80)
		{
			//S456.19 DS ID
			gEmvballocator.EMVBallocator_memset(AppPAN,0,sizeof(AppPAN));
			emvitem = dllemvb_avl_gettagitempointer((unsigned char *)TAG_PAN);
			if(emvitem != NULL)
			{
				if(emvitem->len)
				{
					EMVBcdToAsc(AppPAN,emvitem->data,emvitem->len);
					for(len = 0;len < (emvitem->len<<1);)
					{
						if(AppPAN[len] == 'F'||AppPAN[len] == 'f')
						{
							break;
						}
						len++;
					}
				}
				
			}

			gEmvballocator.EMVBallocator_memset(tempbuf,0,sizeof(tempbuf));
			PANSeq = dllemvb_avl_gettagvalue((unsigned char *)TAG_PANSeq);
            if(len%2)  //  Îªµ¥Êý
            {
            	tempbuf[0] = '0';
				templen++;
            }
			
			//8-11¸ö×Ö½Ú
            if((templen+len+2) < 16)
            {
            	gEmvballocator.EMVBallocator_memset(&tempbuf[templen],'0',16-(templen+len+2));
				templen += 16-(templen+len+2);
            }
			
			gEmvballocator.EMVBallocator_memcpy(&tempbuf[templen],AppPAN,len);
			templen += len;

			EMVBcdToAsc(&tempbuf[templen],&PANSeq,1);

			templen += 2;
			
			
			EMVAscToBcd(AppPAN,tempbuf,templen);
			templen = templen >> 1;
			
			gEmvballocator.EMVBallocator_memset(tempbuf,0,sizeof(tempbuf));
			dllemvb_avl_gettagvalue_all((unsigned char *)TAG_DSID,tempbuf,&len);
			if(templen != len)
			{
				return EMV_ERR;
			}

			if(gEmvballocator.EMVBallocator_memcmp(tempbuf,AppPAN,len))
			{
				return EMV_ERR;
			}
			
		}
		
	}
	
	return EMV_OK;
	
}





unsigned char Paypassb_Getdata_BeforeReadRecord(EMVBAppUnionStruct *tempApp_UnionStruct,unsigned char readrecordparseerr)
{
	EMVTAGCVLITEM *emvitem;
	unsigned char tag[4],taglen;
    unsigned short i;
	APDU_SEND apdu_s;
	APDU_RESP apdu_r;
	//unsigned char retCode;
	//EMVTAGCVLITEM retrunitem;
	unsigned short index;//,len;
    unsigned char ret,bInTable;
	//unsigned char parseok = 0;
	unsigned char *savedtagtoreadret;
    unsigned short savedtagtoreadretlen = 0;
	unsigned char readdataflag = 1;
	unsigned char parsesucflag;
	//S3.76 mag
	if(tempApp_UnionStruct->EMVTradeParam->qPBOCOrMSD == qPBOCTYPE)
	{
		//S3R1.1
		while(readdataflag)
		{
			emvitem = dllemvb_avl_gettagitempointer((unsigned char *)TAG_PAYPSS_TAGSTOREADYET);
			if(emvitem != NULL) //sx2017 ¶ÁÈ¡²¢É¾³ý
			{
				if(emvitem->len)
				{
				    savedtagtoreadret = (unsigned char *)emvblib_malloc(emvitem->len);
					savedtagtoreadretlen = 0;
					parsesucflag = 0;
					for(i = 0;i < emvitem->len;)
					{
						taglen = 0;
						gEmvballocator.EMVBallocator_memset(tag,0,sizeof(tag));

						tag[taglen] = emvitem->data[i];
						if((emvitem->data[i]&0x1f) == 0x1f)
						{
							taglen++;
							tag[taglen] = emvitem->data[i+1];
							if(emvitem->data[i+1]&0x80)
							{
								taglen++;
								tag[taglen] = emvitem->data[i+2];
							}
						}
						taglen++;
						
						if(i + taglen > emvitem->len)
						{
						    emvblib_free(savedtagtoreadret);
							return PAYPASS_PARSEERR;
						}

						
						
						//ÏÖÔÚÖ»Ö§³ÖÁ½¸ö×Ö½ÚµÄ TAG GET DATA
						if(taglen == 2&&tag[0] == 0x9F&&(tag[1] == 0x50||(tag[1] >= 0x70&&tag[1] <= 0x79)))
						{
						    //ÏÈÒÆ³ý
						    gEmvballocator.EMVBallocator_memcpy(&savedtagtoreadret[savedtagtoreadretlen],&emvitem->data[i+taglen],emvitem->len-i-taglen);
							savedtagtoreadretlen += emvitem->len-i-taglen;
							dllemvb_avl_createsettagvalue((unsigned char *)TAG_PAYPSS_TAGSTOREADYET,savedtagtoreadret,savedtagtoreadretlen);
							
							paypassb_command_getdata(&apdu_s,tag,taglen);
							Paypassb_SaveSendAPDUData(&apdu_s,tempApp_UnionStruct);
							paypassb_idsprocess(tempApp_UnionStruct);  //´¦ÀíÒª·ÅÔÚÇ°Ãæ
							tempApp_UnionStruct->EMVTradeParam->ifcmdsaved = 1;
							tempApp_UnionStruct->EMVB_qPBOCIccIsoCommand(&apdu_s,&apdu_r);
							tempApp_UnionStruct->EMVTradeParam->ifcmdsaved = 0;
							if(readrecordparseerr)
							{
							    emvblib_free(savedtagtoreadret);
								return PAYPASS_PARSEERR;
							}
							if(apdu_r.ReadCardDataOk != EMV_OK)
						    {
								//sxl PPSE STOP
							    emvblib_free(savedtagtoreadret);
						    	return ERR_APP_TIMEOUT;
						    }
							
							
							if(apdu_r.SWA == 0x90&&apdu_r.SWB == 0x00)
							{
							    if(apdu_r.LenOut == 0)
							    {
							    	Paypassb_AddDataToList_TLV(tag,NULL,0,(unsigned char *)TAG_PaypassDataToSend);
							    }
								else
								{
								    gEmvballocator.EMVBallocator_memcpy(tempApp_UnionStruct->EMVTradeParam->paypassgetdatatag,tag,2);
									tempApp_UnionStruct->EMVTradeParam->paypassgetdataflag = 1;
									index = 0;
									ret = Paypassb_ParseAndStoreCardResponse(tempApp_UnionStruct,apdu_r.DataOut,&index,&bInTable,0);
									if(index != apdu_r.LenOut)
									{
										ret = ERR_EMV_IccDataFormat;
									}
		                            tempApp_UnionStruct->EMVTradeParam->paypassgetdataflag = 0;
									if(ret != EMV_OK)
									{
										Paypassb_AddDataToList_TLV(tag,NULL,0,(unsigned char *)TAG_PaypassDataToSend);
									}
								}
								
								if(tag[0] == 0x9F&&tag[1] == 0x79)
								{
									i += 0;
								}
							}
							else
							{
								Paypassb_AddDataToList_TLV(tag,NULL,0,(unsigned char *)TAG_PaypassDataToSend);
							}
							parsesucflag = 1;
							break;	
						}
						else
						{
							gEmvballocator.EMVBallocator_memcpy(&savedtagtoreadret[savedtagtoreadretlen],tag,taglen);
							savedtagtoreadretlen += taglen;
						}

						i += taglen;
						
						
					}
					
	                if(parsesucflag == 0)
	                {
	                	readdataflag = 0;
	                }
	                emvblib_free(savedtagtoreadret);
							
				}
				else
				{
					break;
				}
			}	
            else
            {
            	break;
            }
				
		}
		
	}
	#if 0
	else //mag cardÖ»ÒªÖ´ÐÐÒ»´Î
	{
		//S3.76
		Paypassb_AddTLVToList_RemoveTag((unsigned char *)TAG_PAYPSS_TAGSTOREADYET,(unsigned char *)TAG_PaypassDataToSend);
	    //S3.77
	    if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_PaypassDataNeeded)||(dllemvb_avl_checkiftagexist((unsigned char *)TAG_PaypassDataToSend)&&dllemvb_avl_checkiftagexist((unsigned char *)TAG_PAYPSS_TAGSTOREADYET)==0))
	    {
			//S3.78 
			Paypassb_SendDEKSignal(tempApp_UnionStruct,PAYPASSSTEP_S3_78,NULL);
	    }
		
	}
	#endif


    

	return EMV_OK;
}


void paypassb_command_putdata(APDU_SEND *apdu_s,unsigned char *tag,unsigned char taglen,unsigned short tagdatalen,unsigned char *tagdata,unsigned char enablecancel)
{
	gEmvballocator.EMVBallocator_memcpy(apdu_s->Command,"\x80\xDA",2);
	if(taglen == 1)
	{
		apdu_s->Command[2] = 0x00;
		apdu_s->Command[3] = tag[0];
	}
	else
	{
		apdu_s->Command[2] = tag[0];
		apdu_s->Command[3] = tag[1];
	}
	
	apdu_s->Lc = tagdatalen;
	gEmvballocator.EMVBallocator_memcpy(apdu_s->DataIn,tagdata,tagdatalen);
	
	apdu_s->Le = 0;
	apdu_s->EnableCancel = enablecancel;       //Ê¹ÄÜ°´È¡Ïû¼ü
	
}



unsigned char Paypassb_PreGENACPUTDATA(EMVBAppUnionStruct *tempApp_UnionStruct)
{
	
    unsigned char tag[4],taglen,*tagdata;
	unsigned short tagdatalen;
	APDU_SEND *apdu_s;
	APDU_RESP *apdu_r;
	

	tagdata = (unsigned char *)emvblib_malloc(300);
	apdu_s = (APDU_SEND *)emvblib_malloc(sizeof(APDU_SEND));
	apdu_r = (APDU_RESP *)emvblib_malloc(sizeof(APDU_RESP));
	if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_WriteBeforeGAC))
	{
	    while(1)
	    {
	        //S456.42
			if(paypassb_GetAndRemoveFromList((unsigned char *)TAG_PAYPSS_TAGSWYETBGAC,tag,&taglen,tagdata,&tagdatalen))
			{
				if(taglen <3)
				{
				    //S456.50
					paypassb_command_putdata(apdu_s,tag,taglen,tagdatalen,tagdata,1);
					//S456.51
					tempApp_UnionStruct->EMVTradeParam->DisabelDET = 1;
					tempApp_UnionStruct->EMVB_qPBOCIccIsoCommand(apdu_s,apdu_r);
					tempApp_UnionStruct->EMVTradeParam->DisabelDET = 0;
					if(apdu_r->ReadCardDataOk != EMV_OK)
				    {
						//
				    	if(tempApp_UnionStruct->EmvErrID->L3 != EMVB_ERRID_L3_STOP)
				        {
				            Paypassb_SetErrPar(tempApp_UnionStruct,PAYPASSSTEP_S12_5);
				        	Paypassb_packoutsignal(tempApp_UnionStruct,PAYPASSSTEP_S12_6);
				        }
						//
				    	return ERR_APP_TIMEOUT;
						
				    }
					
                    //S12.8
					if(apdu_r->SWA == 0x90&&apdu_r->SWB == 0x00)
					{
						
					}
					else
					{
						break;
					}
					
					
				}
			}
			else
			{
			    //S12.9
			    dllemvb_avl_setvalue_or((unsigned char *)TAG_PREGACPDS,0,0x80);
				break;
			}
	    }
	}


	emvblib_free(tagdata);
	emvblib_free(apdu_r);
	emvblib_free(apdu_s);
	return EMV_OK;
	
}


unsigned char Paypassb_PostGENACPUTDATA(EMVBAppUnionStruct *tempApp_UnionStruct)
{
	
    unsigned char tag[4],taglen,tagdata[300];
	unsigned short tagdatalen;
	APDU_SEND apdu_s;
	APDU_RESP apdu_r;
	
	
	if(dllemvb_avl_checkiftagexist((unsigned char *)TAG_WriteAfterGAC))
	{
	    while(1)
	    {
	        //S456.42
			if(paypassb_GetAndRemoveFromList((unsigned char *)TAG_PAYPSS_TAGSWYETAGAC,tag,&taglen,tagdata,&tagdatalen))
			{
				if(taglen <3)
				{
				    //S456.50
					paypassb_command_putdata(&apdu_s,tag,taglen,tagdatalen,tagdata,0);
					//S456.51
					tempApp_UnionStruct->EMVB_qPBOCIccIsoCommand(&apdu_s,&apdu_r);
					if(apdu_r.ReadCardDataOk != EMV_OK)
				    {
						//
						return EMV_OK;
						
				    }
					
                    //S12.8
					if(apdu_r.SWA == 0x90&&apdu_r.SWB == 0x00)
					{
						
					}
					else
					{
						break;
					}
					
					
				}
			}
			else
			{
			    //S12.9
			    dllemvb_avl_setvalue_or((unsigned char *)TAG_POSTGACPDS,0,0x80);
				break;
			}
	    }

		//?2015
		//S15.10
		
		
	}
	return EMV_OK;
}





void paypassb_OWHF2(EMVBAppUnionStruct *tempApp_UnionStruct,unsigned char *inputPD,unsigned char *outputR)
{
	
	unsigned short PL;
    unsigned char DSID[30];
	unsigned char DSPKL[8];
	unsigned char DSPKR[8],OID[8];
	unsigned char i,dsslotmanagecontrol,dsodsinfo;
	unsigned char KL[8],KR[8];
	
	gEmvballocator.EMVBallocator_memset(DSID,0,sizeof(DSID));
	dllemvb_avl_gettagvalue_all((unsigned char *)TAG_DSID,DSID,&PL);
	for(i = 0;i < 6;i++)
	{
		DSPKL[i] = ((DSID[i]>>4)*10 +( DSID[i]%16))<<1;
		DSPKR[i] = ((DSID[PL-6+i]>>4)*10 +( DSID[PL-6+i]%16))<<1;
	}
    
    
	//OID
	dsslotmanagecontrol = dllemvb_avl_gettagvalue((unsigned char *)TAG_DSSlotManage);
	dsodsinfo = dllemvb_avl_gettagvalue((unsigned char *)TAG_DSODSInfo);
	if((dsslotmanagecontrol&0x80)&&(dsodsinfo&0x40))
	{
		gEmvballocator.EMVBallocator_memset(OID,0,sizeof(OID));
	}
	else
	{
		dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_DSOperatorID,OID,0,8);
	}
	
	
	gEmvballocator.EMVBallocator_memcpy(KL,DSPKL,6);
    gEmvballocator.EMVBallocator_memcpy(&KL[6],&OID[4],2);
	gEmvballocator.EMVBallocator_memcpy(KR,DSPKR,6);
    gEmvballocator.EMVBallocator_memcpy(&KR[6],&OID[6],2);
	
	
    //3DES OIDXORPD
    for(i = 0;i < 8;i++)
    {
    	OID[i] ^= inputPD[i];
    }
	tempApp_UnionStruct->arith_des(1,OID,KL);
	tempApp_UnionStruct->arith_des(0,OID,KR);
	tempApp_UnionStruct->arith_des(1,OID,KL);

	for(i = 0;i < 8;i++)
    {
    	OID[i] ^= inputPD[i];
    }

	gEmvballocator.EMVBallocator_memcpy(outputR,OID,8);
	
}



void paypassb_OWHF2AES(EMVBAppUnionStruct *tempApp_UnionStruct,unsigned char *inputC,unsigned char *outputR)
{
	unsigned char OID[16],M[16],Y[16];
	unsigned char i,dsslotmanagecontrol,dsodsinfo;
	//unsigned short tagdatalen;
	EMVTAGCVLITEM *emvitem;
	
	//OID
	dsslotmanagecontrol = dllemvb_avl_gettagvalue((unsigned char *)TAG_DSSlotManage);
	dsodsinfo = dllemvb_avl_gettagvalue((unsigned char *)TAG_DSODSInfo);
	if((dsslotmanagecontrol&0x80)&&(dsodsinfo&0x40))
	{
		gEmvballocator.EMVBallocator_memset(OID,0,sizeof(OID));
	}
	else
	{
		dllemvb_avl_gettagvalue_spec((unsigned char *)TAG_DSOperatorID,OID,0,8);
	}
	
	gEmvballocator.EMVBallocator_memcpy(M,inputC,8);
	gEmvballocator.EMVBallocator_memcpy(&M[8],OID,8);
	gEmvballocator.EMVBallocator_memset(Y,0,sizeof(Y));
	emvitem = dllemvb_avl_gettagitempointer((unsigned char *)TAG_DSID);
	if(emvitem != NULL)
	{
		if(emvitem->len < 11)
		{
			gEmvballocator.EMVBallocator_memcpy(&Y[11-emvitem->len],emvitem->data,emvitem->len);
		}
		else
		{
			gEmvballocator.EMVBallocator_memcpy(Y,emvitem->data,11);
		}
	}
	
	//K
	gEmvballocator.EMVBallocator_memcpy(&Y[11],&OID[4],4);
	Y[15] = 0x3F;

	gEmvballocator.EMVBallocator_memcpy(OID,M,16);
	tempApp_UnionStruct->arith_aes(1,OID,Y,16);  //sxl?2017
    for(i = 0;i < 8;i++)
    {
    	M[i] ^= OID[i];
    }
	
	gEmvballocator.EMVBallocator_memcpy(outputR,M,8);
	
	
}


#endif


